我们可以在php中的另一个类中创建一个类的对象吗?

May*_*tar 7 php class object

我们可以在php中的另一个类中创建一个类的对象吗?我在php中创建了一个小应用程序,现在我试图以类方法对象的方式转换整个代码.我现在很困惑.

Gor*_*don 17

您可以这样做,但是否应该取决于两个类的生命周期及其相互之间的关系.基本上,您可以在CompositionAggregation之间进行选择.

组成

当创建的对象的生命周期等于或小于将使用它的对象时,可以使用Composition,例如

class A 
{
    private $belongsToAOnly;

    public function __construct()
    {
        $this->belongsToAOnly = new IBelongToA;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下A"拥有" IBelongToA.什么时候A被毁坏,IBelongToA也被毁坏了.它不能独立生存,可能只是一个实现细节A.这可能是一个的ValueObjectMoney或某种其他数据类型.

来自Craig Larman的"应用UML和模式":

复合材料负责创建和删除它的部分 - 通过自身创建/删除部分,或通过与其他对象协作.与此约束相关的是,如果复合材料被销毁,其部件必须被销毁或附加到另一个复合材料"

聚合

当创建的对象的生命周期更长时,您使用聚合:

class A 
{
    private $dbAdapter;

    public function __construct(DbAdapter $dbAdapter)
    {
        $this->dbAdapter = $dbAdapter;
    }
}
Run Code Online (Sandbox Code Playgroud)

与Composition不同,这里没有所有权的含义.A使用DbAdapterA被摧毁的时候依然DBAdapter存在.这是一种"使用"关系,而不是"拥有"关系.

创作者模式(GRASP)

可以在GRASP中的创建者模式中找到一个很好的启发式方法来决定对象何时可以在运行时创建另一个对象,该创建者模式指出对象可以创建其他对象时

  • B的实例包含或复合聚合A的实例
  • A的B记录实例的实例
  • B的实例密切使用A的实例
  • B的实例具有A实例的初始化信息,并在创建时传递它.

或者,您可以在需要创建某些实例并聚合工厂实例时创建工厂,这样可以更清晰地分离协作者和创建者.

可测性

在对象内创建对象的问题是它们很难测试.当您进行单元测试时,通常不希望重新创建和引导整个系统环境,而是专注于单独测试该特定类.为此,您将该类的依赖项与Mock对象交换.使用Composition时,不能这样做.

因此,根据类的协作者所做的事情,您可能希望决定始终使用聚合,因为这样您就可以一直有效地执行依赖注入,这将允许您轻松地交换类的协作者,例如替换他们与模拟.


Sam*_*ane 6

是的,你可以,但这会增加代码耦合并使测试更难.
我建议在类之外创建它并将其作为参数传递(它称为依赖注入).

class Foo
{
}

class Bar
{
  public function __construct(Foo $foo)
  {
    $this->foo = $foo;
  }
}

$foo = new Foo();
$bar = new Bar($foo);
Run Code Online (Sandbox Code Playgroud)

  • 链接是因为我没有关于依赖注入的争论的空间,链接只是一个注释,但如果你想打开一个线程只讨论软件架构,欢迎你.如果没有上下文,你就不能断言有一件事是不好的做法,问题没有上下文,你只是在没有论据的情况下暴露你的意见. (2认同)