Does it make sense to clone copies of dependencies (Injection Dependency)?

Let's say I have a class that has several methods that depend on another object to do its duty. The difference is that they all depend on the same class of the object, but they need different instances of the class. Or, more specifically, each method needs a clean instance of the class, because the methods will change the state of the dependency.

Here is a simple example that I had in mind.

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'; } } 

Technically, I could do this.

 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'; } } 

My problem is that I constantly have to check that the dependent object is being transferred in the correct state. The state is newly created. So instead, I was thinking of just doing something like this.

 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'; } } 

This allows me to get one instance of the object in the correct state, and I can just copy it if I need another. I am just wondering if that makes sense, or if I am over the fundamental guide regarding dependency injection and code checking.

+4
source share
3 answers

I would use the Factory pattern for this:

 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'; } } 

You can split Factory further by entering an interface:

 interface DependencyFactoryInterface { public function create(); } class DependencyFactory implements DependencyFactoryInterface { // ... } class Something { public function __construct(DependencyFactoryInterface $factory) ... 
+4
source

DI is a great design, but that does not mean that it is right for any occasion. In your particular case, you said that you need a “fresh” copy every time, which means that just using “new” to create a new instance makes more sense than using DI.

The idea of ​​DI is a loose connection - and allows different places in the code to use the same object (knowing nothing about it except the interface that it implements), but in your case you do not need to reuse the object, so I would not use DI here.

+1
source

If doSomething() and doSomethingElse() perform the same actions in two functions, then this is a bad choice. In this case, a feeder function is created and two different objects of this function are transferred.

But if there are two responsible for two different actions that require the cloning of the dependency object, then this is not bad.

0
source

Source: https://habr.com/ru/post/1493337/


All Articles