8

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

4

5 回答 5

18

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

作品

当创建的对象的生命周期等于或小于将使用它的对象时,您使用组合,例如

class A 
{
    private $belongsToAOnly;

    public function __construct()
    {
        $this->belongsToAOnly = new IBelongToA;
    }
}

在这种情况下A“拥有” IBelongToA。当A被摧毁时,IBelongToA也被摧毁。它不能独立存在,很可能只是A. 它可以是类似ValueObjectMoney其他一些数据类型。

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

复合体负责创建和删除它的部分 - 通过它自己创建/删除部分,或者通过与其他对象协作。与此约束相关的是,如果复合材料被破坏,它的部分必须被破坏,或者附加到另一个复合材料上”

聚合

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

class A 
{
    private $dbAdapter;

    public function __construct(DbAdapter $dbAdapter)
    {
        $this->dbAdapter = $dbAdapter;
    }
}

与 Composition 不同,这里没有所有权的含义。A使用DbAdapter,但当A被破坏时仍然DBAdapter存在。这是一种“使用”关系,而不是“拥有”关系。

创建者模式 (GRASP)

可以在 GRASP中的创建者模式中找到一个很好的启发式来决定一个对象何时可以在运行时创建另一个对象

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

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

可测试性

在对象中创建对象产生的一个问题是它们难以测试。当您进行单元测试时,您通常不想重新创建和引导整个系统环境,而是专注于单独测试那个特定的类。为此,您可以使用Mock Objects替换该类的依赖项。使用合成时不能这样做。

因此,根据一个类的协作者所做的事情,您可能想要决定始终使用聚合,因为这样您就可以一直有效地进行依赖注入,这将允许您轻松交换一个类的协作者,例如替换他们和 Mocks。

于 2012-05-20T11:51:53.630 回答
8

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

class Foo
{
}

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

$foo = new Foo();
$bar = new Bar($foo);
于 2012-05-17T10:38:26.990 回答
4

是的,你可以做到..

这是一个例子..

a.php
<?php
    class a{
        public function function_1(){
           echo "b";
        }
     }
?>


b.php
<?php
     include_once ("a.php");
     class b{
        public function function_b(){
             $a = new a;
             $a->function_1();
        }
      }
      $b= new b;
      $b->function_b();
 ?>
于 2012-05-17T10:54:29.640 回答
3

是的,您可以从另一个类中的特定类创建对象。

class SomeClass{

}
class SomeOtherClass {
     function hello(){
         $o = new SomeClass;
     }
}
于 2012-05-17T10:34:06.600 回答
2

是的,你也可以在一个类中定义一个函数。您可以在 php 中的类中完成所有操作,请将您的代码发布在您感到困惑的地方。

示例:类中的对象。

class Foo
{
   public $bar; // another object!

   public __construct()
   {
      $this->bar = new Bar();
    }
}

(全局)类中的函数

<?php
    class Foo
    {
        public function __construct()
        {
            function __construct()
            {
                echo "Yes, I'm a global function!";
            }
        }
    }

    new Foo();
    __construct();

?>
于 2012-05-17T10:33:12.500 回答