5

假设我有一个类,它有一些依赖于另一个对象的方法来执行它们的职责。不同之处在于它们都依赖于同一类对象,但需要该类的不同实例。或者更具体地说,每个方法都需要一个干净的类实例,因为这些方法将修改依赖项的状态。

这是我想到的一个简单的例子。

class Dependency {
    public $Property;
}


class Something {
    public function doSomething() {
        // Do stuff
        $dep = new Dependency();
        $dep->Property = 'blah';
    }

    public function doSomethingElse() {
       // Do different stuff
       $dep = new Dependency(); 
       $dep->Property = 'blah blah';
    }
}

从技术上讲,我可以做到这一点。

class Something {
    public function doSomething(Dependency $dep = null) {
        $dep = $dep && is_null($dep->Property) ? $dep : new Dependency();
        $dep->Property = 'blah';
    }

    public function doSomethingElse(Dependency $dep = null) {
       $dep = $dep && is_null($dep->Property) ? $dep : new Dependency();
       $dep->Property = 'blah blah';
    }
}

我的麻烦是我必须经常检查传入的依赖对象是否处于正确状态。新创建的状态。所以相反,我只想做这样的事情。

class Something {
    protected $DepObj;

    public function __construct(Dependency $dep) {
        $this->DepObj = $dep && is_null($dep->Property) ? $dep : new Dependency();
    }
    public function doSomething() {
        // Do stuff
        $dep = clone $this->DepObj;
        $dep->Property = 'blah';
    }

    public function doSomethingElse() {
       // Do different stuff
       $dep = clone $this->DepObj;
       $dep->Property = 'blah blah';
    }
}

这允许我获得一个处于正确状态的对象实例,如果我需要另一个实例,我可以复制它。我只是好奇这是否有意义,或者我是否正在寻找有关依赖注入和保持代码可测试的基本指南。

4

3 回答 3

4

我会为此使用工厂模式:

class Dependency {
    public $Property;
}

class DependencyFactory
{
    public function create() { return new Dependency; }
}

class Something {
    protected $dependencies;

    public function __construct(DependencyFactory $factory) {
        $this->dependencies = $factory;
    }

    public function doSomething() {
       // Do different stuff
       $dep = $this->dependencies->create();
       $dep->Property = 'Blah';
    }

    public function doSomethingElse() {
       // Do different stuff
       $dep = $this->dependencies->create();
       $dep->Property = 'blah blah';
    }
}

你可以通过引入一个接口来进一步解耦工厂:

interface DependencyFactoryInterface
{
    public function create();
}

class DependencyFactory implements DependencyFactoryInterface
{
    // ...
}

class Something {
    public function __construct(DependencyFactoryInterface $factory) 
    ...
于 2013-07-25T03:21:14.250 回答
1

DI is a wonderful design pattern, but that doesn't mean it's the right one for any case. In your specific case you said that you need a "fresh" copy every time, which means that simply using "new" to create a new instance makes more sense than using DI.

The idea behind DI is loose coupling - and allowing different places in the code to use the same object (knowing nothing about it other then the interface it implements) - but in your case you don't need to re-use an object, hence I wouldn't use DI here.

于 2013-07-25T02:15:56.267 回答
0

如果doSomething()and doSomethingElse()both 在两个函数中做类似的事情,那么这是一个糟糕的选择。在这种情况下,它创建了一个 feeder 函数并将两个不同的对象提供给该函数。

但是,如果两者都负责需要克隆依赖对象的两个不同的操作,那就不错了。

于 2013-07-25T02:09:35.627 回答