第二十三章、外观模式
外观模式是结构型设计模式之中的一个。它在开发中的运用频率非常高。是我们封装API的经常使用手段。我们经常使用的三方SDK基本都使用的外观模式,这样能够对用户屏蔽非常多实现细节。减少用户使用成本。
1.定义
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更易于使用。
2.使用场景
(1)为复杂子系统提供一个简单接口。对外隐藏子系统的详细实现、隔离变化。
(2)当你须要构建一个层次结构的子系统时。使用外观模式定义子系统中每层的入口点。假设子系统之间是相互依赖的,你能够让它们仅通过外观接口进行通信,从而简化了它们之间的依赖关系。
3.UML类图
(1)Facade
:系统对外的统一接口,系统内部系统地工作。
(2)其它分支
:子系统接口。
能够看出外观模式结构非常easy,可是假设没有封装,那么用户就要操作几个子系统的交互逻辑。easy出现错误。
4.简单实例
手机集合了电话功能、短信功能、拍照和GPS等功能。那么以手机为例。简单的用外观模式实现一下。
Phone接口与PhoneImpl:
public interface Phone {
//拨电话
public void dail();
//挂断
public void hangup();
}
public class PhoneImpl implements Phone{
@Override
public void dail() {
System.out.println("打电话");
}
@Override
public void hangup() {
System.out.println("挂断");
}
}
Camera接口与Camera的实现类:
public interface Camera {
//打开相机
public void open();
//拍照
public void takePicture();
//关闭相机
public void close();
}
public class SamsungCamera implements Camera{
@Override
public void open() {
System.out.println("打开相机");
}
@Override
public void takePicture() {
System.out.println("拍照");
}
@Override
public void close() {
System.out.println("关闭相机");
}
}
外观类MobilePhone:
public class MobilePhone {
private Phone mPhone = new PhoneImpl();
private Camera mCamera = new SamsungCamera();
public void dail(){
mPhone.dail();
}
public void hangup() {
mPhone.hangup();
}
public void takePicture() {
mCamera.open();
mCamera.takePicture();
}
public void closeCamera() {
mCamera.close();
}
public void videoChat(){
System.out.println("--> 视频聊天接通中");
mCamera.open();
mPhone.dail();
}
}
调用:
public class Client {
public static void main(String[] args) {
MobilePhone mobilePhone = new MobilePhone();
//拍照
mobilePhone.takePicture();
//视频聊天
mobilePhone.videoChat();
}
}
结果:
打开相机
拍照
--> 视频聊天接通中
打开相机
打电话
5.Android源代码中的外观模式
1.Context
Context
是一个抽象类,它的真正实现是ContextImpl
类,通过查看ContextImpl
源代码我们能够看到ContextImpl
内部封装了非常多不同子系统的操作。
比如:Activity的跳转、发送广播、启动服务和设置壁纸等。这些工作不是在ContextImpl
中实现。而是交给了详细的子系统进行处理。通过Context
这个抽象类定义了一组接口,ContextImpl
实现。这样用户通常情况下就不须要对每一个子系统进行了解。这样对用户屏蔽了详细的实现细节。减少了使用成本。
6.总结
1.长处
(1)对客户程序隐藏子系统的细节,因而减少了客户对于子系统的耦合,能够拥抱变化。
(2)外观类对子系统的接口封装,使得系统更易于使用。
2.缺点
(1)外观类接口膨胀。因为子系统的接口都有外观类统一对外暴露。使得外观类的API接口较多。在一定程度上添加了用户使用成本。
(2)外观类没有遵循开闭原则,当业务出现变更时。可能须要直接改动外观类。