php - 工厂方法可能违反 Demeter 法则?

标签 php oop factory law-of-demeter

从这里引用:https://en.wikipedia.org/wiki/Law_of_Demeter

More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:[2]

  • O itself

  • m's parameters

  • Any objects created/instantiated within m

  • O's direct component objects

  • A global variable, accessible by O, in the scope of m

In particular, an object should avoid invoking methods of a member object returned by another method

所以细节:

class O
{
    private $c;
    public function m($obj1)
    {
        $this->a(); // OK
        $obj1->a(); // OK
        (new C())->a(); // OK
        $c->a(); // OK
        $a = function() { };
        $a(); // OK
    }

    private function a() {}
}

现在第三定律值得怀疑。所以我新创建了一个对象。但如果我不是:

(new C())->a();

我愿意:

$this->factory->createC()->a();

还有效吗?一个常规类被实例化,只是不是通过 new 而是通过工厂。但是,嘿!法律说:

In particular, an object should avoid invoking methods of a member object returned by another method

按照这个规则,工厂方法失败了!怎么办?真的失败了吗?

最佳答案

我不这么认为。

尤其是这个:

Any objects created/instantiated within m

我也会将其应用于工厂。即使严格来说对象的构造函数是在工厂中调用的,对象仍然是由 for m 构造的。我会把工厂解释为一种特殊的构造函数,并且忽略你在那里没有看到 new 关键字的事实。

鉴于工厂在软件设计中扮演的各种重要角色(控制反转是其中之一),我认为它们太有值(value)了,不能放手。最好改变您对该法则或构造函数是什么的解释,并在需要时使用这些工厂。

关于php - 工厂方法可能违反 Demeter 法则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53529338/

相关文章:

java - 如何在接口(interface)中获取非抽象方法?

c++ - 错误 C2259 : 'class' : cannot instantiate abstract class

java - 如何创建路径 bean

java - 从泛型类派生类型

php - Json编码带空格的字符串

ios - swift 从另一个类访问类类型变量

php - .htaccess RewriteRule 与 PHP INCLUDE 或 REQUIRE 不起作用?

oop - 抽象工厂是否引入紧耦合

php - 如何获取当前访问的html页面并存储在php my sql中

php - 从一个表中选择结果,并为每一行选择另一个表中具有相同 id 的所有行