Android设计模式-22-外观模式
2018-06-21 本文已影响71人
今阳说
1. 定义
- 隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口
- 通过创建一个统一的类,用来包装子系统中一个或多个复杂的类
(由外观类去保存各个子系统的引用,实现由一个统一的外观类去包装多个子系统类,然而客户端只需要引用这个外观类,然后由外观类来调用各个子系统中的方法)
2. 使用场景
- 为复杂的模块或子系统提供外界访问的接口
- 子系统相对独立
- 预防低水平人员带来的风险
3. 优缺点
- 优点:
- 降低了客户类与子系统类的耦合度,实现松耦合关系
- 对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单。
- 降低原有系统的复杂度和系统中的编译依赖性,并简化了系统在不同平台之间的移植过程
- 缺点:
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
4. Android源码中的使用:
Context封装了很多操作,如startActivity(),sendBroadcast(),bindServiced()等,相当于抽象外观类,Context的子系统中去实现这些方法,如ActivityManagerService实现startActivity(),PackageManagerService实现包信息相关方法,ContextImpl则是Context的实现类,也就是外观类,其内部调用这些子系统的实现,而Activity相当于客户端,其上两层父类ContextWrapper中有个一个Context类型的mBase字段,其实际类型是ContextImpl,是对外观类的调用,例如ContextWrapper中:
@Override
public Resources getResources() {
return mBase.getResources();
}
5. 实例演示
以智能家居,统一管理家电为例
- 各种家电作为子系统,如灯,电视,空调等
public class Light {
public void on() {
LjyLogUtil.i("开灯...");
}
public void off() {
LjyLogUtil.i("关灯...");
}
}
public class Televison {
public void on() {
LjyLogUtil.i("开电视...");
}
public void off() {
LjyLogUtil.i("关电视...");
}
}
public class Aircondition {
public void on() {
LjyLogUtil.i("开空调...");
}
public void off() {
LjyLogUtil.i("关空调...");
}
}
- 智能遥控器作为外观类(现在很多有红外功能的Andorid手机都有智能遥控器app, 比如我常用的遥控精灵就挺好用,不用再去抱着一大堆的各种遥控器)
/**
* 智能遥控器
*/
public class SmartControl {
private Light mLight = new Light();
private Televison mTelevison = new Televison();
private Aircondition mAircondition = new Aircondition();
/**
* 开所有电器
*/
public void allOn() {
lightOn();
tvOn();
airOn();
}
/**
* 关所有电器
*/
public void allOff() {
lightOff();
tvOff();
airOff();
}
public void lightOn() {
mLight.on();
}
public void lightOff() {
mLight.off();
}
public void tvOn() {
mTelevison.on();
}
public void tvOff() {
mTelevison.off();
}
public void airOn() {
mAircondition.on();
}
public void airOff() {
mAircondition.off();
}
}
- 通过外观类去操作各子系统
private void methodFacadePattern() {
SmartControl smartControl = new SmartControl();
smartControl.airOn();
smartControl.airOff();
smartControl.tvOn();
smartControl.tvOff();
smartControl.allOn();
smartControl.allOff();
}