外观模式
为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式三要素(client-facade-subSystem)
- 外观角色(facade),是模式的核心,他被客户client角色调用,知道各个子系统的功能。同时根据客户角色已有的需求预订了几种功能组合。
- 子系统角色(subsystem),实现子系统的功能,并处理由Facade对象指派的任务。对子系统而言,facade和client角色是未知的,没有Facade的任何相关信息;即没有指向Facade的实例。
- 客户角色(client),调用facade角色获得完成相应的功能。
java代码
class SubSystemA{
public void start(){
System.out.println("system A starts.");
}
}
class SubSystemB{
public void start(){
System.out.println("system B starts.");
}
}
class Facade{
SubSystemA systemA=new SubSystemA();
SubSystemB systemB=new SubSystemB();
public void start(){
systemA.start();
systemB.start();
}
}
class Client {
public static void main(String[] args) {
Facade facade=new Facade();
facade.start();
}
}
优点
- 对客户端屏蔽了子系统,是的子系统使用起来更加容易。
- 子系统和客户端松耦合。
- 降低编译依赖性,简化了系统在不同平台之间的移植过程。
- 也可以直接访问子系统。
注意:不要试图通过外观类为子系统增加新行为!
不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。
缺点
- 不能很好的限制客户端对子系统的调用。
- 增加子系统,需要修改外观类,如果外观类不进一步抽象的话。
JDK中的外观模式
如:java.lang.Class中,Class类充当了外观角色,Reflection类为子系统角色。
//如forName方法,为Reflection类,提供了一个简单的访问API
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}