模式介绍
- 外观模式在开发过程中运用频率非常高,尤其现在各种第三方SDK“充斥”在我们的开发中,这些SDK大多会使用外观模式。通过一个外观类是的整个系统的接口只有一个统一的高层接口,这样能够降低用户的使用成本,也能够对用户屏蔽很多实现细节。外观模式也是我们封装API的常用手段,例如网络模块、ImageLoader模块等。还有我们平时使用的ide,ide就是外观类,客户端也就是开发人员通过debug按钮调用其debug子系统等等。
定义与类型
- 定义:又叫门面模式,提供一个统一的接口,用来访问子系统中的一群接口
- 外观模式定义了一个高层接口,让子系统更容易使用
- 类型:结构型
使用场景
- 子系统越来越复杂,增加外观模式提供简单调用接口
- 构造多层系统结构,利用外观对象作为每层的入口,简化层间调用
优点
- 简化了调用过程,无须了解、深入子系统,防止带来风险
- 减少系统依赖、松散耦合
- 更好的划分访问层次
- 符合迪米特法则,即最少知道原则
缺点
- 增加子系统、扩展子系统行为容易引入风险
- 不符合开闭原则
相关设计模式 - 外观模式和中介模式:外观模式关注的是
外界与子系统间
的交互,而终结者关注的是子系统内部间
的交互 - 外观模式和单例模式:通常可以把
外观对象
设计成单例模式 - 外观模式和抽象工厂模式:外观类可以通过抽象工厂获取子系统的实例,子系统可以从内部对外观类进行屏蔽
UML类图:
Facade-Pattern.png
简单示例
- 外观类MobilePhone:
public class MobilePhone{
private Phone mPhone = new phoneImpl();
private Camera mCamera = new CameraImpl();
public void deil(){
mPhone.dail();
}
public void close(){
mPhone.hangup();
}
public void takePicture(){
mCamera.takePicture();
}
}
- 子系统抽象接口:
public interface Phone{
//打电话
void dail();
//挂电话
void hangup();
}
public interface Camera{
//拍照片
void takePicture();
}
- 子系统实例:
public class phoneImpl implements Phone{
@Override
public void dail() {
System.out.println("打电话");
}
@Override
public void hangup() {
System.out.println("挂电话");
}
}
public class cameraImpl implements Camera{
@Override
public void takePicture() {
System.out.println("拍照片");
}
}
- 客户端调用
public static void main(String[] args) {
MobilePhone s10 = new MobilePhone();
s10.deil();
s10.hashCode();
}
外观模式在源码中的应用
- android开发中熟悉的Context上下文我们可以通过它的实现类
ContextImpl
来启动activity(startActivity()),ContextImpl就是外观类,实际实现是通过ActivityManagerService来启动的。还有获取应用包相关信息则是通过PackageManagerService。 - mybatis中的Configuration:
public class Configuration {
'省略代码'
protected final InterceptorChain interceptorChain = new InterceptorChain();
'省略代码'
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
Configuration是外观类
,InterceptorChain是子系统
,通过外观类Configuration的newParameterHandler方法调用子系统InterceptorChain获取具体产品。