众所周知,包装类的重点是封装另一个类或组件的功能。这是一个包含PHP Predis库的一小部分的简单类:
class CacheWrapper {
private $client;
public function __construct(){
$this->client = new Predis\Client();
}
public function set($key, $value){
$this->client->set($key, $value);
}
public function get($key){
return $this->client->get($key);
}
}
以下是使用此包装类的简单代码:
$client = new CacheWrapper();
echo $client->get('key1');
这个类可以完美地解决它在类中创建依赖项的问题,我希望通过将依赖项注入类而不是让类创建其依赖项来避免它,因此包装类看起来像这样:
class CacheWrapper {
private $client;
public function __construct(Predis\Client $predisObj){
$this->client = $predisObj;
}
public function set($key, $value){
$this->client->set($key, $value);
}
public function get($key){
return $this->client->get($key);
}
}
所以我必须编写以下代码来使用包装类:
$predis = new Predis\Client();
$client = new CacheWrapper($predis);
echo $client->get('key1');
但我认为没有必要使用包装类,因为我仍然在我的代码中使用原始类。所以我的问题是:依赖注入和包装类概念是否相互冲突,不能一起使用,解决这类问题的最佳方法是什么?
答案 0 :(得分:1)
众所周知,包装类的要点是封装了 另一个类或组件的功能
这实际上并不准确。 “包装类”并不像你暗示的那么简单。有许多设计模式可以“包装”一个类。
当所需的API与您拥有的类的API不匹配时,适配器模式“包装”一个对象。
Facade模式为更大的代码体提供了简化的界面。
Class A{
String setValueFirstHalf(String)
String setValueSecondHalf(String)
Void getValue()
}
// Pseudo-code for 'wrapper' that is an 'adapter pattern' impl.
// This class 'wraps' A and changes the API
Class WrapsA_Adapter{
String setFirst(String) {myA.setValueFirstHalf(String)}
String setSecond(String) {myA.setValueSecondHalf(String)}
Void get() {myA.getValue()}
}
// Pseudo-code for 'wrapper' that is an 'facade pattern' impl.
// This class 'wraps' A and changes the API to 'simplify' it.
// Often the 'facade pattern' uses several classes to do its task,
// but it 'can' use just one like we did below. (this example is obviously a stretch)
Class WrapsA_Facade{
String get()
Void set(String first, String second){
myA.setValueFirstHalf (first);
myA.setValueSecondHalf(second);
}
}
现在直接回答你的问题:
依赖注入和包装类概念是否违背每一个 其他的,不能一起使用,最好的解决方法是什么 像这样的问题?
他们本身并不相互对立。
您可以非常轻松地使用WrapperFacade实现,其中Facade注入了接口的“特定”实例。
如果适配器正在调整接口,并且您正在注入该接口的特定实现以供其使用,则具有依赖项注入的适配器模式也将是有效的。
答案 1 :(得分:0)
如果您确切知道要扩展的对象,那么最好使用普通继承。
依赖注入是指当您知道将扩展/使用满足某些基本条件的类时,但可能超过或由其他开发人员定义的类。在这种情况下,您将代码设置为需要基类(或接口),并让您的类的用户确切地确定要扩展的实现。
<强> TL;博士强>
如果您的课程将始终用作:
$predis = new Predis\Client();
$client = new CacheWrapper($predis);
echo $client->get('key1');
然后依赖注入不添加任何有用的东西。但是,如果它可能是:
$other = new OtherPredisLikeClass\Client();
$client = new CacheWrapper($other);
echo $client->get('key1');
然后,依赖注入允许您的类的用户使用它而无需重写您的类。