包装器 类 和依赖注入

wrapper classes and dependency injection

众所周知,wrapper classes 的意义在于封装了另一个class 或组件的功能。这是一个简单的 Class,它包装了 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);

}

 }

这里是使用这个包装器的简单代码 class :

$client = new CacheWrapper();
echo $client->get('key1');

这个 class 可以完美工作的问题是它在 class 内部创建了依赖项,我想通过将依赖项注入 class 而不是让 class 来创建它的依赖项,因此包装器 class 将如下所示:

    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);

}

 }

所以我必须编写以下代码来使用包装器 class :

    $predis = new Predis\Client();
    $client = new CacheWrapper($predis);
    echo $client->get('key1');

但我认为没有必要使用包装器 class,因为我仍然在我的代码中使用原始的 class。所以我的问题是:依赖注入和包装器 class 概念是否相互矛盾并且不能一起使用,解决此类问题的最佳方法是什么?

当您确切知道要扩展的对象时,最好使用普通继承。

依赖注入适用于当您知道自己将 extending/using class 满足某些基本条件但可能超出此条件或由其他开发人员定义的情况。在那种情况下,您将代码设置为需要一个基础 class(或接口),并让您的 class 的用户确切地决定要扩展哪个实现。

tl;dr

如果您的 class 将始终用作:

$predis = new Predis\Client();
$client = new CacheWrapper($predis);
echo $client->get('key1');

然后依赖注入没有添加任何有用的东西。但是,如果它可能是:

$other = new OtherPredisLikeClass\Client();
$client = new CacheWrapper($other);
echo $client->get('key1');

然后依赖注入让你的 class 的用户无需重写你的 class.

就可以使用它

As everybody knows, the point of wrapper classes is encapsulates the functionality of another class or component

这实际上并不准确。 "Wrapper Classes" 并不像你暗示的那么简单。有许多设计模式 "wrap" a class。

适配器模式 'wraps' 当所需的 API 与您拥有的 class 的 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);
    }
}

参见:Adapter pattern, Facade pattern


现在直接回答你的问题:

does dependency injection and wrapper class concepts goes against each other and can't be used together and what is the best way to solve issue like this ?

他们并不是天生对立的。

您可以很容易地拥有一个 WrapperFacade 实现,其中 Facade 注入了接口的 'specific' 实例。

如果适配器正在适配接口,并且您正在注入该接口的特定实现以供其使用,则具有依赖项注入的适配器模式也将有效。