维基百科中提到了适配器模式,用于修复预期接口和实际接口之间的不兼容性。
据说,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
}
这种实施背后的理由是什么?
答案 0 :(得分:1)
我将一次使用分析1模式 -
适配器模式上面给出的分类器示例看起来像一个适配器,因为它适应(通过对象适配器的经典定义)从ClassifierImplementation到Classifier - 但它并没有真正适应你提到的方法是相同的一种类型到另一种类型。因此,如果一切都一样 - 为什么要适应!!
外观模式 - 它不是外观,因为外观是为了简化界面(在这种情况下是方法),而在这种情况下,方法/方法定义对于ClassifierImplementation和Classifier是相同的。 ClassifierImplementation似乎更像是一个包装器(正如你所提到的)而不是分类器,它将我带到了下一点 -
最后,所有的说法和完成,ClassifierImplementation类应该重命名为更有意义的东西(如 ClassifierProxy ),因为它没有扩展或实现任何东西。当前名称会造成混淆并降低可读性。
注意 - ClassifierImplementation可以实现分类器正在实现的相同接口,但它更像是一个装饰器而不是代理。
答案 1 :(得分:1)
我遇到过一个代码,其中包装类是使用内部类的接口的精确副本实现的 - 它具有原始的所有公共方法,具有完全相同的参数。包装类和内部类也在同一个程序集中定义。
这种实施背后的理由是什么?
一个原因是创建一个包装类可以实现的抽象。
这方面的一个例子是ASP.NET中的HttpContext
类。最初的ASP.NET实现是一个名为HttpContext
的类,它有一个非常大而复杂的接口。
当单元测试进入场景时,很快发现仅为单元测试创建此类的实例并不是很实用,因为类本身具有多个依赖项和无法设置的只读属性。 / p>
因此,在.NET的更高版本中,HttpContextBase
抽象类的创建与HttpContext
完全相同。此外,它附带了一个名为HttpContextWrapper
的具体实现,它将HttpContext
实例作为构造函数参数。
现在,测试更容易,因为测试中的代码只需要依赖HttpContextBase
。为了满足被测代码的逻辑,很容易使用模拟库一次定义几个属性。
实时应用程序通常会注入HttpContextWrapper
,因为它与HttpContext
具有完全相同的接口,它与非可模拟的HttpContext
类完全相同在生产中。
具有相同的接口意味着要使现有代码可测试,只需将变量或参数引用从HttpContext
更改为HttpContextBase
,其他代码都不需要更改。