不确定我的标题是否正确,因为我甚至不确定我使用的术语是否正确。
我有一个类,它的属性是一个对象。设置此属性时,必须创建对象。我的问题是,在没有紧耦合的情况下,如何做到这一点?
例子:

class A
{
    protected $_depending;

    protected $_somePropertyObject;

    public function __construct(\Lib\Dependency $depending)
    {
        $this->_setDepending($depending);
    }

    protected function _setDepending(\Lib\Dependency $depending)
    {
        $this->_depending = $depending;
    }

    public function setSomeProperty($someProperty)
    {
        // I want to prevent this
        $this->_somePropertyObject = new \Lib\some\Object($someProperty);
    }
}

我可以通过构造传递所需的对象,但是还需要什么呢?
如果我正确地理解了工厂模式,会有什么变化?我还需要在某处创建对象吗?不是物体本身而是工厂。又是紧耦合?对我来说似乎没完没了。然而,当重新分解类时,它是独立的类在何处以及如何生成的。
如果我将setsomeproperty函数设置为只接受\lib\some\object,则仍然需要由传递它的父对象创建。似乎只是改变了它被创造的位置?
希望我能清楚地知道我想问的问题。
提前谢谢!
编辑我要问的是在什么时候,在哪里,为什么创建的序列。

最佳答案

依赖注入模式中的工厂的目的是为另一个实例生成实例,而不需要另一个实例知道如何生成实例。
在其核心,“工厂”只是一个对象返回器:调用时返回实例的东西。
这在功能更强的语言中更容易看到。例如,在python中,类是可调用的(没有new操作符),调用类会生成类的实例。因此,如果类不需要参数,则类可以是它们自己的工厂。同样,任何返回实例的零参数函数都可以被视为工厂。这使得依赖注入非常清晰,没有样板文件。
在更严格的语言中(java/c++/c;静态类型的传统,或者类或函数不像php那样是完全一流的),您需要隐藏“模式”背后的依赖注入,因为"design patterns" are missing language features。在php 5.3+中,可以使用闭包作为工厂,也可以使用java/c方式,为每个工厂定义一个FactoryInterface和一个新类。
例如,对于您的类,您可以执行以下操作:

class Aprime extends A
{
    public function setSomeProperty($somePropertyFactory)
    {
        $this->_somePropertyObject = $somePropertyFactory();
    }
}

在这个类中,setSomeProperty需要一个可调用的零参数“factory”,您可以这样生成:
$other_dep_factory = function(){ return new SomeOtherClass(); };

或者像这样:
class ClassFactory {
    function __construct($classname, $args=array()) {
        $this->class = new ReflectionClass($classname);
        $this->args = $args;
    }

    function __invoke() {
        return $this->class->newInstanceArgs($this->args);
    }
}

$other_dep_factory = new ClassFactory('SomeOtherClass');

在php 5.3之前,您需要像java那样:
interface IObjectFactory {
    function getObject();
}

// this B-and-D interface is optional
// it has no body because PHP doesn't support
// type-hinting return values
interface ISomeOtherClassFactory {}


class SomeOtherClassFactory implements ISomeOtherClassFactory {
    function getObject() {
        return new SomeOtherClass();
    }
}

class Aprime extends A
{
    public function setSomeProperty(ISomeOtherClassFactory $somePropertyFactory)
    {
        $this->_somePropertyObject = $somePropertyFactory->getObject();
    }
}


$other_dep_factory = new SomeOtherClassFactory();
$myAprimeObject->setSomeProperty($other_dep_factory);

你什么时候用工厂?当一个对象需要创建另一个对象时。如果对象只需要使用另一个对象,只需传入一个实例。

10-07 12:17
查看更多