一、介绍,定义
外观模式在开发中使用较高,尤其在现阶段,第三方SDk的使用。
SDK大多使用外观模式。
通过一个外观类是的整个系统的接口只有一个统一的高层接口,
这样就能降低用户成本,也对用户屏蔽了很多实现细节。
外观模式也是我们封装API的常用手段,例如网络模块、ImageLoader模块等。
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。
外观模式提供一个高层次接口,使得子系统更易于使用。
二、使用场景
1为一个复杂的子系统提供一个简单接口。
2构建一层次结构的子系统,子系统间相互依赖,则通过 Facade 接口进行通信,从而简化他们的依赖关系。
三、UML类图
四、简单实现
这里以一个手机为例。然后再更精简一点。手机可以看成是一个系统的facade,他继承了电话,上网,摄像头功能。当我们需要视频通话时,只需要调用手机的视频通话功能就行,通话结束后直接调用挂机就行。因为手机已经集成了这些功能,手机内部会调用各个系统来完成这个操作。
想象一下如果没有手机的封装,我们视频通话的操作可能就是:打开摄像头–上网–通话。然后挂断就要手动断掉通话,然后手动关掉摄像头。
电话功能模块:
public interface Phone {
void dail();
void hangup();
}
public class PhoneImpl implements Phone {
@Override
public void dail() {
System.out.println("打电话");
}
@Override
public void hangup() {
System.out.println("挂断");
}
}
摄像头模块:
public interface Camera {
void open();
void takePicture();
void close();
}
public class CameraImpl implements Camera {
@Override
public void open() {
System.out.println("打开相机");
}
@Override
public void takePicture() {
System.out.println("开始视频");
}
@Override
public void close() {
System.out.println("关闭相机");
}
}
然后封装一个门面:
public class MobilePhone {
private Phone phone = new PhoneImpl();
private Camera camera = new CameraImpl();
public void videoChat(){
camera.open();
phone.dail();
}
public void hangup(){
phone.hangup();
camera.close();
}
}
客户端直接调动统一的接口:
public class Client {
public static void main(String[] args) {
MobilePhone mobilePhone = new MobilePhone();
mobilePhone.videoChat();
System.out.println("----");
mobilePhone.hangup();
}
}
五、模式的优缺点:
外观模式的精髓在于 封装。通过一高层次结构为用户提供统一的 API 入口,使得用户通过一个类就基本能够操作整个系统。
外观模式的优缺点
优点
- 对客户端隐藏子系统细节,因而减少客户对于子系统的耦合。
- 外观类对子系统的接口封装,使得系统更易于使用。
缺点
1)接口膨胀。由于子系统都有外观类统一对外暴露,使得外观类的API接口较多,在一定程度上增加了用户的使用成本。 - 外观类没有遵循开闭原则,当业务出现变更时,可能需要直接修改外观类。