一 定义
外观模式也称作门面模式,也是一种常用的封装模式,其定义如下:
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
也就是说,对于一个复杂的系统,我们可以通过一个外观类使得整个系统的接口只有一个统一的高层接口,这样降低了客户端的使用成本,也屏蔽了很多实现细节。
二 模式结构
角色介绍:
- Facade:系统对外的统一接口,系统内部系统地工作。
- SystemA,SystemB,SystemC:子系统接口。
外观模式比较简单,就是通过一个统一的接口对外提供服务,使得外部程序只通过一个类就可以实现系统内部的多种功能。
三 实例
我们以生活中常用的手机为例,我们知道手机集成了多种功能,打电话,上网,拍照等等,用户通过手机就可以完成这些功能,所以手机相当于给了用户一个统一的入口,正是外观模式的Facade,而集成的各种功能相当于各个系统,下面通过外观模式来实现。
- 定义打电话功能,电话系统及其实现
/**
* 打电话系统
*/
public interface Phone {
// 打电话
void call();
// 挂断电话
void hangup();
}
public class PhoneImpl implements Phone{
@Override
public void call() {
System.out.println("打电话");
}
@Override
public void hangup() {
System.out.println("挂断电话");
}
}
- 拍照功能,拍照系统及其实现
/**
* 拍照系统
*/
public interface Camera {
// 打开照相机
void openCamera();
// 拍照
void takePicture();
// 关闭照相机
void close();
}
public class CameraImpl implements Camera{
@Override
public void openCamera() {
System.out.println("打开相机");
}
@Override
public void takePicture() {
System.out.println("拍照");
}
@Override
public void close() {
System.out.println("关闭相机");
}
}
- 上网功能
/**
* 上网系统
*/
public interface Internet {
void netPlay();
}
public class InternetImpl implements Internet{
@Override
public void netPlay() {
System.out.println("上网");
}
}
- 定义统一的接口服务类
在这个类中,可以根据实际需要重新组合上面的功能。
/*
* 统一的外部接口
* @author Jackson
* @version 1.0.0
* since 2019 03 26
*/
public class MobilePhone {
private Phone mPhone=new PhoneImpl();
private Camera mCamera=new CameraImpl();
private Internet mInternet=new InternetImpl();
public void dail(){
System.out.println("---------使用打电话功能----------");
mPhone.call();
mPhone.hangup();
}
public void takePicture(){
System.out.println("---------使用拍照功能----------");
mCamera.openCamera();
mCamera.takePicture();
mCamera.close();
}
public void videoChat(){
System.out.println("---------使用视频聊天----------");
mInternet.netPlay();
mCamera.openCamera();
mPhone.call();
}
}
- 测试代码
MobilePhone xioaMi=new MobilePhone();
// 打电话
xioaMi.dail();
// 拍照
xioaMi.takePicture();
// 视频聊天
xioaMi.videoChat();
-
运行结果
四 优点
- 松散耦合
外观模式松散了客户端和子系统之间的耦合关系,使得子系统内部的各个模块更容易扩展和维护。 - 简单易用
外观类对子系统的接口封装,客户端不在和子系统进行交互,使得系统更易于使用。 - 更好地规划访问层次。
客户端要使用的功能,必须要在Facade中开通方法,通过合理使用Facade,可以更好地规划系统的功能。
缺点
不合理的Facade,会造成外观类的API接口过多,使得用户不确定到底是使用Facade好还是直接调用子模块好,会增加用户的使用成本。
五 使用场景
- 如果你希望为一个复杂的模块或系统提供一个供外部访问的接口,可以考虑使用外观模式。
- 如果你想要客户类和抽下类实现松散耦合,可以考虑使用外观模式。
- 如果你想构建都层次的系统,可以考虑使用外观模式。
网友评论