降低接口复杂度(Reducing interface complexity)
有时候你需要解决的是很简单的问题,比如“当前的接口不是你正好需要的”。Façade模式(外观)通过为库或者一堆资源提供一个更易用的使用方法,为一系列类创建一个接口。
外观Façade 当我想方设法试图将需求初步(first-cut)转化成对象的时候,通常我使用的原则是:“把所有丑陋的东西都隐藏到对象里去”。基本上说,Façade干的就是这个事情。如果你有一堆让人头晕的类以及Interactions? ,而它们又不是客户端程序员必须了解的,那你就可以为客户端程序员创建一个接口只提供那些必要的功能。 Façade模式经常被实现为一个符合singleton模式的抽象工厂(abstract factory)。当然,你可以通过创建包含静态工厂方法(static factory methods)的类来达到上述效果。
//: facade:Facade.java package facade; import junit.framework.*; class A { public A(int x) {} } class B { public B(long x) {} } class C { public C(double x) {} } // Other classes that aren't exposed // by the facade go here ... public class Facade extends TestCase { static A makeA(int x) { return new A(x); } static B makeB(long x) { return new B(x); } static C makeC(double x) { return new C(x); } public void test() { // The client programmer gets the objects // by calling the static methods: A a = Facade.makeA(1); B b = Facade.makeB(1); C c = Facade.makeC(1.0); } public static void main(String args[]) { junit.textui.TestRunner.run(Facade.class); } } ///:~
《设计模式》给出的例子是通过一个类使用另外一个类(来实现façade模式的)。 税务顾问是你和税法(tax code)之间的façade,他也是你和税务系统之间的中间人(mediator)。
Package作为façade的变体 我感觉,façade更倾向于“过程式的(procedural)”,也就是非面向对象的(non-object-oriented):你是通过调用某些函数才得到对象。它和Abstract factory到底有多大差别呢? Façade模式关键的一点是隐藏某个库的一部分类(以及它们的交互),使它们对于客户端程序员不可见,这样那些类的接口就更加简练和易于理解。 其实,这也正是java的packaging功能所完成的事情:在库以外,你只能创建和使用被声明为公共(public)的那些类;所有非公共(non-public)的类只能被同一package的类使用。看起来,façade似乎是java内嵌的一个功能。 To be fair,《设计模式》主要是写给C++读者的。尽管C++有命名空间 (namespaces) 机制来防止全局变量和类名称之间的冲突,但它并没有提供类隐藏的机制,而在java里你可以通过声明non-public类实现这一点。我认为,大多数情况下java的package功能就足以解决针对façade模式的问题了。
目录

|