适配器模式和依赖

时间:2012-01-12 16:14:04

标签: oop design-patterns

我对适配器类没有什么疑问。我知道适配器类的目标是什么。何时应该使用。我怀疑是关于班级建设。我已经检查了一些教程,并且所有人都说我应该将“Adaptee”类作为依赖项传递给我的“Adapter”。 e.g。

Class SampleAdapter implements MyInterface
{
    private AdapteeClass mInstance;
    public SampleAdapter(AdapteeClass instance)
    {
         mInstance=instance;
    }
}

此示例是从维基百科复制而来的。正如您所见,AdapteeClass作为依赖项传递给我的对象。问题是为什么?如果我正在改变对象的界面很明显我将使用“新”界面,我不需要“旧”界面。为什么我需要在我的适配器外创建“旧”类的实例。有人可能会说我应该使用依赖注入,所以我可以传递任何我想要的,但这是适配器 - 我需要更改具体类的接口。就我个人而言,我认为代码更好。

Class SampleAdapter implements MyInterface
{
    private AdapteeClass mInstance;
    public SampleAdapter()
    {
         mInstance= new AdapteeClass();
    }
}

您有什么看法?

4 个答案:

答案 0 :(得分:8)

我想说,当涉及到复杂的对象时(除了类是BuilderFactory之外),你应该总是避免类中的new运算符,以减少耦合并使代码更好测试。可以在类方法中构造像List或Dictionary或值对象这样的课程对象(这可能是类方法的目的!)

让我们举例来说,你的AdapteeClass是Remote Proxy。如果您想使用单元测试,您的单元测试必须使用真正的代理类,因为在单元测试中无法替换它。

如果您使用第一种方法,则在运行单元测试时可以轻松地将模拟或假冒注入构造函数中,以便您可以测试所有代码路径。

Google有guide on writing testable code更详细地描述了这一点,但有些重点是:

  

不可测试代码的警告标志

     
      
  • 构造函数或字段声明中的新关键字
  •   
  • 构造函数或字段声明中的静态方法调用
  •   
  • 除了构造函数中的字段赋值之外的任何内容
  •   
  • 构造函数完成后对象未完全初始化(注意初始化方法)
  •   
  • 构造函数中的控制流(条件或循环逻辑)
  •   
  • 代码在构造函数中执行复杂的对象图构造,而不是使用工厂或构建器
  •   
  • 添加或使用初始化块
  •   

答案 1 :(得分:1)

AdapteeClass可以有一个或多个非平凡的构造函数。在这种情况下,您需要在SampleAdapter构造函数中复制所有这些内容以具有相同的灵活性。传递已构造的对象更简单。

答案 2 :(得分:0)

我认为在Adapter中创建Adaptee是有限的。如果有一天你想要调整预先存在的实例怎么办?

说实话,如果可能的话,我会做两件事。

Class SampleAdapter implements MyInterface
{

    private AdapteeClass mInstance;

    public SampleAdapter()
       : base (new AdapteeClass())
    {
    }

    public SampleAdapter(AdapteeClass instance)
    {
         mInstance=instance;
    }
}

答案 3 :(得分:0)

假设您有一个带有常规 USB 端口的外置硬盘,并且您正尝试将其连接到只有 type-c 端口的 Mac。是的,您可以购买一个带有 type-c 端口的新驱动器,但是里面的数据呢?

适配器模式也是如此。有时您会用大量的口味初始化 AdapteeClass。进行转换时,您希望保留所有上下文。