工厂方法可能违反得墨忒耳法?

Joh*_*ith 8 php oop factory law-of-demeter

引用自:https://en.wikipedia.org/wiki/Law_of_Demeter

更正式地说,函数的Demeter法则要求对象O的方法m只能调用以下类型的对象的方法:[2]

  • O本身

  • m的参数

  • 在m中创建/实例化的任何对象

  • O的直接组件对象

  • 一个全局变量,可由O访问,范围为m

特别是,对象应该避免调用另一个方法返回的成员对象的方法

所以详细说明:

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() {}
}
Run Code Online (Sandbox Code Playgroud)

现在第3条法律值得怀疑.所以我新创建了一个对象.但如果我而不是:

(new C())->a();
Run Code Online (Sandbox Code Playgroud)

我做:

$this->factory->createC()->a();
Run Code Online (Sandbox Code Playgroud)

它还有效吗?一个普通的课程被实例化,只是new一个工厂而已.但是嘿!该法律说:

特别是,对象应该避免调用另一个方法返回的成员对象的方法

按此规则,工厂方法失败!怎么办?它真的失败了吗?

Gol*_*rol 6

我不这么认为.

尤其是:

m中创建/实例化的任何对象

我也会把它应用到工厂.即使严格地在工厂中调用对象的构造函数,该对象仍然由,尤其 m构造.我会将工厂解释为一种特殊的构造函数,并且看一看你没有看到new关键字的事实.

鉴于工厂在软件设计中扮演的各种重要角色(控制反转就是其中之一),我认为它们太有价值而无法放手.最好改变你对这个定律的解释,或改变构造函数的解释,并在你想要的时候使用这些工厂.