繁体   English   中英

OOP(php)在另一个类中实例化类

[英]OOP (php) instantiating class within another class

不确定我是否选择了正确的标题。 但无论如何。

我必须支持并开发已有的项目。

它建立在OOP之上。

我有Order,Product这样的模型。 它们经常用于代码中。

每个模型都绑定到相应的表。

客户希望将新类型的客户集成到系统中。 这类客户拥有与之相关的不同数据,并订购完全不同类型的产品。 所以订单会有所不同。

我决定的是不要混合旧的秩序和新的秩序。 首先,我将它们放入分离的表中,以便不破坏工作系统并为它们创建不同的类。

现在我有Order.php和OrderNew.php,Product.php和ProductNew.php等模型。

我有全局设置对象,其中属性包含我需要实例化的类型。

现在我搞了很多代码:

if ($global->object->isNewKindOfCustomer())  {
   $product = new ProductNew;   
} else {
   $product  = new Product;
}

但是在很多地方这样做我都有强烈的感觉,我做了一件非常错误的事情。

所以我的第一个想法是应该由类Product决定应该实例化什么样的产品。

如果我可以转到旧的Product类并在其构造函数中执行并执行某些操作,那将是完美的:

Class Product {
  __construct() {
    if ($global->object->isNewKindOfCustomer())  {
      $product = new ProductNew;   
    } else {
       $product  = new Product();
    }
  }
 }

另外,我将从Product继承ProductNew并重新定义需要更改的所有方法。 就像是:

Class ProductNew extends Product {

  public methodsDefinedInProductButInNeedToBeChangedForProductNew (){
  }
}

但问题是,我没有找到一个理智的方式在PHP中做它,它仍然闻起来不太好。 但比第一种方法好得多(至少对我而言)。

第三个想法是,我现在将创建ProductNew类,但也创建ProductOld类(不存在但我本身得到的东西)。

我将所有代码从当前的Product类移动到ProductOld。 所以我目前的Product类没有方法。 它会变空。 此外,ProductNew将继承自ProductOld。

有这样的方案我根本不会触及整个系统的代码。 在代码中的任何地方,assignemnts将具有以下外观

$product  = new Product

在内部我将需要以某种方式管理将在Product构造函数中创建的对象。

第四个想法是我将首先创建一个泛型类,并将其命名为例如ProductGeneral。 它将包含与ProductNew和ProductOld类相关的方法。 他们都将扩展ProductGeneral。 而在Product内部,只会根据当前用户的角色实例化适当的类。 虽然我不确定ProductGeneral是否如此必要......

仍然不知道如何在Product类中替换它。 我记得它在C ++中被称为动态绑定。

有没有更好的解决方案来解决这个问题? 我错过了什么吗?

对不起太长的文字,我确实试着让它尽可能短。

 if ($global->object->isNewKindOfCustomer()) { $product = new ProductNew; } else { $product = new Product; } 

但是在很多地方这样做我都有强烈的感觉,我做了一件非常错误的事情。

我同意。 这就是最重要的。
Assimung $global->object global- $global->object的类型为Customer ,添加一个可以根据需要覆盖的方法newProduct

class Customer
{
    public function newProduct()
    {
        return new Product();
    }
}

class CustomerNew extends Customer
{
    public function newProduct()
    {
        return new ProductNew();
    }
}

然后,您必须确切地检查一下您是在处理新客户类型还是旧客户类型(在实例化CustomerCustomerNew ),而不是再次。
这基本上是“工厂模式”,而不是一个单独的类。

此外,我建议你将所有共同点放在一个新的基类上,而不是拥有一个“正常”的旧类和一个新的重写类。

abstract class CustomerBase
{
    // Define here all methods that Customer and CustomerNew have in common

    // And make "implementation-dependent" methods abstract:
    public abstract function newProduct();
}

class Customer extends CustomerBase
{
    public function newProduct()
    {
        return new Product();
    }
}

class CustomerNew extends CustomerBase
{
    public function newProduct()
    {
        return new ProductNew();
    }
}

这将是一个“更清晰”的实现(语义上),您仍然不必使用CustomerOld或其他东西替换代码中的每个Customer
我建议你用Product做同样的事情,而不是仅仅覆盖“默认”的方法

您可能需要具有所有基本函数的Product类,具有特定于该类的函数的ProductOld ,以及具有特定于该类的函数的ProductNew 此外,还有一个ProductFactory ,它将返回您需要的产品类。

如果没有看到代码,很难说是否最好在上面做,或者只是extend Product类并拥有一个ProductFactory

哦不:(完全错了。

Class Product {
  __construct() {
    if ($global->object->isNewKindOfCustomer())  {
      $product = new ProductNew;   
    } else {
       $product  = new Product();
    }
  }
 }

你在哪里得到$global 它不在你的构造函数中。 你无法从任何地方获得实例。 这会产生不可测试的代码

您正在寻找工厂模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM