PHP构造函数和相互依赖的字段的反弹

时间:2012-06-01 09:24:47

标签: php design-patterns object constructor

MyClass有一个反弹字段,其中每个值都取决于另一个实例值,最后是DependencyClass。一个非常简单的例子:

解决方案A(使用构造函数)

public class MyClass
{
    private $myField1, $myField2;

    public function MyClass(DependencyClass $dependency)
    {
        $value = $dependency->getValue();
        $value++; // Computations on dependency value

        $this->myField1 = $value + 3;
        $this->myField2 = $value - 1;
    }

    public function getMyField1()
    {
        return $this->myField1;
    }

    public function getMyField2()
    {
        return $this->myField2;
    }
}

我的问题是,类构造函数是我应该放置此计算逻辑的正确位置吗?或者更适合做一些代码重复,如:

解决方案B(仅用于依赖的构造函数)

public class MyClass
{
    private $dependency;

    public function MyClass(DependencyClass $dependency)
    {
        $this->dependency= $dependency
    }

    public function getMyField1()
    {
        $value = $this->dependecy->getValue();
        $value++; // Computations on dependency value

        return $value + 3;
    }

    public function getMyField2()
    {
        $value = $this->dependecy->getValue();
        $value++; // Computations on dependency value

        return $value - 1;
    }
}

或使MyClass仅仅是一个容器,并且用户是外部汇编程序类,如:

解决方案C(外部汇编程序)

Class Assembler
{
    public getMyClass()
    {
        $dependency = new Dependency();
        $value      = $dependency->getValue();
        $value++; // Computations on dependency value

        $myClass = new MyClass();
        $myClass->setMyField1($value + 3);
        $myClass->setMyField2($value - 1);

        return $myClass;
    }

}

2 个答案:

答案 0 :(得分:1)

答案是“它取决于”。你想要完成什么?

使用解决方案A和B,您已经与依赖关系进行耦合,并且计算是MyClass对象的固有部分:MyClass与Dependency不存在,并且它始终以某种方式使用依赖关系。另一方面,解决方案C完全将MyClass与Dependency分离,使MyClass成为一个不起眼的数据对象。

所以问题是,在特定时刻面对你的任何具体案例中,哪一个是有意义的。您是否希望将来能够以各种方式构建MyClass中的数据,或者您是否希望始终从依赖关系中创建数据?

答案 1 :(得分:1)

这取决于您的环境和需求。

如果您的计算很简单且经常使用,我会把它们放在ctor中。 (解决方案A)

如果其中一个计算很复杂和/或不总是使用,我会在访问器中选择“延迟评估”,并让访问者在计算结果后缓存结果。 (解决方案B,但我会添加结果的缓存)。

我建议不要使用解决方案C.它实际上只是不同范围内的构造函数,因此您的类没有凝聚力。它隐藏了对另一个类的依赖。这使得测试变得困难,因为其他类不能被模拟或存根。该类没有什么理由存在 - 它与只读数组几乎相同。