外观模式在我们身边是最常见的了。就拿手机来说,手机中有各种模块,相机,gps,通信,音视频等等,这些全部集成到手机上,只要在手机上点点屏幕就可以轻松使用这些功能。还有各种第三方SDK,这些SDK往往会提供一个统一的接口供我们调用,让开发者很轻松的就可以将SDK集成到自己的系统中。
定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行;提供一个高层次的接口,使得子系统更易于使用。
结构:
- 外观角色:在客户端可以调用它的方法,在外观角色中可以知道相关的子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理
- 子系统角色:实现相应的功能;每个子系统都可以被客户端直接调用,或者被外观角色调用;子系统并不知道外观类的存在,对于子系统而言,外观类仅仅是另外一个客户端而已
适用场景:
- 为一个复杂子系统提供一个简单的接口。子系统往往因为不断演化而变得越来越复杂,甚至可能被替换
- 当你需要构建一个层次结构的子系统时,使用外观模式定义子系统中每层的入口点。如果子系统之间相互依赖,可以让它们仅通过Facade接口进行通信,此达到简化依赖关系的目的
UML类图:
下面就是外观模式的编码实现,这里以手机为例子:
子系统:
public class Camera {
void takePhoto(){
System.out.println("使用相机模块拍摄照片");
}
}
public class GPS {
void location(){
System.out.println("使用GPS模块定位");
}
}
public class Communication {
void call(){
System.out.println("使用通信模块打电话");
}
}
Facade:
public class MobilePhone {
private Camera camera = new Camera();
private Communication communication = new Communication();
private GPS gps = new GPS();
public void call(){
communication.call();
}
public void takePhoto(){
camera.takePhoto();
}
public void location(){
gps.location();
}
}
Test:
public class Test {
public static void main(String[] args){
MobilePhone mobile = new MobilePhone();
mobile.call();
mobile.takePhoto();
mobile.location();
}
}
总结:外观模式是一个高频使用的设计模式,它的核心就是封装。通过一个高层次结构为用户提供一个统一的API入口,使得用户通过一个类型就基本能够操作整个操作系统,减少了用户的使用成本,也提升了系统的灵活性。但显然外观模式是没遵循开闭原则的,当业务出现变更时,可能需要直接修改外观类。
参考:《Android源码设计模式解析与实战》