降低接口复杂度(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模式的问题了。
目录
本文地址:http://com.8s8s.com/it/it28288.htm