外观模式
通过一个外观关联客户类和子系统
动机
网站首页,通过一个首页将客户和各个子系统分离开来
定义
- 对象结构型模式
- 通过一个统一的外观对象来进行客户端和子系统的通信
- 定义一个高层接口来使子系统更加容易被使用
结构
外观类:关联子系统——转发调用
子系统类:本身存在的子系统
分析
- 迪米特法则的体现:一个对下给你尽可能降低与其他对象的关系
- 引入一个新的外观角色来降低复杂度
- 子系统是一个广义的概念,可以包含很多:类,功能模块,系统的组成部分或则一个完整的系统
- 只是单纯的将子系统类和外观类关联起来即可,不用进行泛化
实例
GeneralSwitchFacade类
public class GeneralSwitchFacade {
private Light lights[]=new Light[4];
private Fan fan;
private AirConditioner ac;
private Television tv;
public GeneralSwitchFacade()
{
lights[0]=new Light("左前");
lights[1]=new Light("右前");
lights[2]=new Light("左后");
lights[3]=new Light("右后");
fan=new Fan();
ac=new AirConditioner();
tv=new Television();
}
public void on()
{
lights[0].on();
lights[1].on();
lights[2].on();
lights[3].on();
fan.on();
ac.on();
tv.on();
}
public void off()
{
lights[0].off();
lights[1].off();
lights[2].off();
lights[3].off();
fan.off();
ac.off();
tv.off();
}
}
Light类
public class Light
{
private String position;
public Light(String position)
{
this.position=position;
}
public void on()
{
System.out.println(this.position + "灯打开!");
}
public void off()
{
System.out.println(this.position + "灯关闭!");
}
}
其余类似的不作重复介绍
Client类
public class Client
{
public static void main(String args[])
{
GeneralSwitchFacade gsf=new GeneralSwitchFacade();
gsf.on();
System.out.println("-----------------------");
gsf.off();
}
}
运行结果
优点
- 减少客户端要处理的对象数目
- 子系统和客户端之间的松耦合关系
- 一个子系统修改对其他子系统没有任何影响,子系统内部变化也不会影响到外观对象
缺点
- 不能很好地限制客户端直接使用子类系统
- 增加新的子系统有可能修改外观类的源代码,违背开闭原则
适用场景
- 一系列复杂的子系统提供一个简单的入口
- 客户端程序与多个子系统之间存在较大的依赖
- 层次化结构中,适用外观模式定义系统中每一层的入口,层与层之间不直接产生了联系,降低耦合度
扩展
将外观模式也进行一层抽象,新增子系统时就可以新增外观类来符合开闭原则