Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 使用适配器/门面模式预测不兼容的接口和复杂性?_Design Patterns_Adapter_Facade - Fatal编程技术网

Design patterns 使用适配器/门面模式预测不兼容的接口和复杂性?

Design patterns 使用适配器/门面模式预测不兼容的接口和复杂性?,design-patterns,adapter,facade,Design Patterns,Adapter,Facade,Wikipedia中提到适配器模式是为了修复预期接口和实际接口之间的不兼容 Facade模式据说会掩盖复杂的实现,并提供一个简化的API 然而,即使没有这些问题,也会使用这些模式吗?Aka,为了预测未来的不兼容性和复杂性而过早地使用这些模式 我遇到过这样的代码:包装类是使用内部类接口的精确副本实现的——它具有原始类的所有公共方法,并且具有完全相同的参数。包装类和内部类也在同一程序集中定义 像这样: public class ClassifierImplementation { priva

Wikipedia中提到适配器模式是为了修复预期接口和实际接口之间的不兼容

Facade模式据说会掩盖复杂的实现,并提供一个简化的API

然而,即使没有这些问题,也会使用这些模式吗?Aka,为了预测未来的不兼容性和复杂性而过早地使用这些模式

我遇到过这样的代码:包装类是使用内部类接口的精确副本实现的——它具有原始类的所有公共方法,并且具有完全相同的参数。包装类和内部类也在同一程序集中定义

像这样:

public class ClassifierImplementation
{
    private Classifier classifier_;
    public Wrapper() { classifier_ = new Classifier(); }

    public int[] Classify(double[] values, int seed)
    {
        return classifier_.Classify(values, seed);
    }

    // And other more public methods
}

这种实现背后的基本原理是什么?

我将一次使用分析1模式-

  • 适配器模式上面给出的分类器示例看起来像是一个适配器,因为它将ClassifierImplementation(对象适配器的经典定义)调整为分类器,但它并不是真的从一种类型调整为另一种类型,因为您提到的方法是相同的。因此,如果一切都一样,为什么要适应

  • 门面模式-它不是门面,因为门面用于简化接口(本例中的方法),而在本例中,方法/方法定义与ClassifierImplementation和Classifier相同。ClassifierImplementation似乎更像是一个包装器(正如您也提到的)而不是分类器,这就引出了我的下一点-

  • 代理模式-它看起来像一个代理模式实例,其中ClassifierImplementation试图控制对其所持有的分类器实例的访问。通过这种方式,分类器实现可以根据需要修改传入请求参数或传出返回值,并且方法定义不会更改
最后,不管怎么说,ClassifierImplementation类应该被重命名为更有意义的类(比如ClassifierProxy),因为它没有扩展或实现任何东西。当前名称会造成混乱并降低可读性

注意-ClassifierImplementation可以实现分类器正在实现的同一接口,但它更像是一个装饰器而不是代理

我遇到过这样的代码:包装类是使用内部类接口的精确副本实现的——它具有原始类的所有公共方法,并且具有完全相同的参数。包装类和内部类也在同一程序集中定义

这一实施背后的理由是什么

一个原因是创建包装类可以实现的抽象

ASP.NET中的
HttpContext
类就是一个例子。最初的ASP.NET实现是一个名为
HttpContext
的类,它有一个非常大和复杂的接口

当单元测试出现时,人们很快发现,仅为单元测试创建此类的实例并不实用,因为类本身有几个无法设置的依赖项和只读属性

因此,在.NET的更高版本中,
HttpContextBase
抽象类是使用与
HttpContext
完全相同的接口创建的。此外,它附带了一个名为
HttpContextWrapper
的具体实现,该实现将
HttpContext
实例作为构造函数参数

现在,测试要容易得多,因为被测试的代码只需要依赖于
HttpContextBase
。为了满足被测代码的逻辑,使用模拟库一次只定义几个属性是很容易的

实时应用程序通常会将
HttpContextWrapper
注入其中,因为它与
HttpContext
具有完全相同的接口,所以它与生产中不可模仿的
HttpContext
类的功能完全相同


具有相同的接口意味着使现有代码可测试,只需要将变量或参数引用从“代码> HtpValue改为HtpCutExbase< /C> >,其他代码都不需要更改。< /P>我询问了原始DEV,答案是因为C++约定。在C++中,如果我们提供了一个只有.CyfFY()方法的.h文件,那么用户可以根据.h文件编译他们的代码。我们可以随时交换实际的库-用户不需要重新编译,只需要重新链接(iirc)。一个适配器模式,如果我得到它正确,但也解决了在C++编译器和链接器级别的关注点。第一个似乎是将接口简化为几个属性(以便将来的测试更容易编写),第二个似乎是减少对现有测试用例的更改(只是一个简单的查找/替换)。我做对了吗?不太熟悉依赖项注入,但我认为这意味着您不需要在项目引用中重新编译或引用注入的程序集?