Dependency Injection. Is it better to go through the full class or class name?

For dependency injection, I understand that I need to transfer an instance of one class to the main instance instead of the main class, creating its own instance, for example (php):

class Class_One { protected $_other; public function setOtherClass( An_Interface $other_class ) { $this->_other_class = $other_class; } public function doWhateverYouHaveToDoWithTheOtherClass() { $this->_other_class->doYourThing(); } } interface An_Interface { public function doYourThing(); } class Class_Two implements An_Interface { public function doYourThing() { } } class Class_Three implements An_Interface { public function doYourThing() { } } // Implementation: $class_one = new Class_One(); $class_two = new Class_Two(); $class_three = new Class_Three(); $class_one->setOtherClass( $class_two ); $class_one->doWhateverYouHaveToDoWithTheOtherClass(); $class_one->setOtherClass( $class_three ); $class_one->doWhateverYouHaveToDoWithTheOtherClass(); 

Everything is good. I know that since both the Class_Two and Class_Three classes implement An_Interface, they can be used interchangeably in Class_One. Class_One would not know the difference between the two.

My question is, is it ever better to use an instance for setOtherClass, pass a string like "Class_Two", and the Class_One setOtherClass method actually creates the instance itself like this:

 class Class_One { ... public function setOtherClass( $other_class_name ) { $this->_other_class = new $other_class_name(); } ... } 

Is such a defeat of the goal of the Injection of Dependence, or is it completely true? I thought this type of customization could help me with customization where the user can specify which class he wants to use in the string earlier, and this can be passed to Class_One later ..

Actually, having written this, I thought that this is probably not a very good solution, but I will post it anyway if someone can give me good feedback on why I should / should not do this.

Thanks =)

Ryan

+4
source share
3 answers

This theoretically hits the goal of an addiction injection; you tell Class_One, which depends on An_Interface, which concrete implementation of this interface it should create. This requires Class_One to know how to instantiate ANY An_Interface by closely associating Class_One with all An_Interface implementations. If you add a new An_Interface Class_Four, you need to go back and tell Class_One how to instantiate the Class_Four class.

In PHP, you avoid this AS LONG AS, all An_Interface implementations have a parameterless constructor. However, if any implementation needs OTHER dependencies that you enter, you are screwed; you cannot tell Class_One only the new Class_Four class if Class_Four needs a Class_Five, which Class_One does not know about.

+5
source

Pass the object specified by the interface. Otherwise, as you will always know with 100% accuracy, what is required to build an object?

 public function __construct(MyInterface $object) { } 

Thus, it doesnโ€™t matter how you create the object, you just need to know if you can use it (the interface against which you are programming) ...

+3
source

In any case, this is technically equivalent to IMO. The main test to determine if you are injecting dependencies correctly is to see if you are using any constant strings with "new" or with static method calls. Your code looks good if the classes in the implementation section can be changed through configuration or some other mechanism. The only drawback with passing the string name of the class is that you cannot be sure that it implements a specific interface or extends any other object. Checking for this can become erratic. However, if your application can handle this problem gracefully, then you should be fine. Transferring an actual instance of an object, although this is the best method.

0
source

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


All Articles