一、外观模式概述
外观模式定义与意图:外观类为复杂的子系统提供了一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。(对象结构型模式)
- 外观模式的特点:
- 1.又叫做门面模式;
- 2.是迪米特法则的一种具体实现;
- 3.通过引入一个新的外观角色来降低原有系统的复杂度,同时降低客户类与子系统的耦合度;
- 4.所指的子系统是一个广义的概念,它可以是一个类,一个功能模块,系统的一个组成或者一个完整的系统。
- 外观模式分析:
- 1.一个客户类需要喝多个业务类交互,而这些需要交互的业务类经常会作为一个整体出现;
- 2.引入一个新的外观类(Facade)来负责和多个业务类(子系统(Subsystem))进行交互,而客户类只需与外观类交互;
- 3.为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。
- 外观模式的引入:
- 1.没有外观类:每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度将很大;
- 2.引入外观类:客户类只需要直接与外观类交互,客户类与子系统之间原有的复杂引用关系由外观类来实现,从而降低了系统的耦合度;
- 3.一个子系统的外部与其内部的通信通过一个同意的外观类进行,外观类将客户类与子系统的内部复杂性分隔开,是得客户类只需要与外观角色打交道,而不需要与子系统内部得跟多对象打交道。
- 4.简化接口:外观类为复杂的子系统提供了一个简单得访问入口。
- 模式优缺点:
- 优点:
- 1.它对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更容易;
- 2.它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要吊针给外观类即可;
- 3.一个子系统的修改对其他子系统没有任何影响,而且子系统的内部比那花也不会影响到外观对象。
- 缺点:
- 1.不能很好地陷制客户端直接使用子系统类,如果客户端访问子系统类做太多的限制则减少了可变性和灵活性;
- 2.如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。
- 优点:
- 模式适用环境:
- 1.要为访问一系列复杂的子系统提供一个简单入口;
- 2.客户端与多个子系统之间存在很大的依赖性;
- 3.在层析结构中,可以使用外观模式的定义系统中每一层的入口,层与层之间不直接产生联系,二十通过外观类建立联系,降低层之间的耦合度。
二、代码实现
外观模式结构包含两个角色:
- 外观角色(Facade)
- 子系统角色(Subsystem)
抽象外观类的动机:在标准的外观模式的结构图中,如果需要增加、删除或更换与外观类交互的子系统类,必需修改外观类或客户端的源代码,这将违背开闭原则,因此可以通过引入抽象外观类对系统进行改进,在一定程度上解决该问题。
利用外观模式设计一个保安系统的,由录像机、电灯、红外线监控和警报器组成。保安系统的操作人员需要经常将这些仪器启动和关闭。保安类需要用到所有的录像机(Camera)、电灯(Light)、感应器(Sensor)和警报器(Alarm)对象,保安觉得使用不方便。编程实现并绘制该模式的UML图。
2.1 外观角色(console以及实现console控制的接口Equipment)
package facade.securitySystem;
//开关接口
public interface Equipment {
public void turnOn(); // 打开设备
public void turnOff(); // 关闭设备
}
package facade.securitySystem;
//控制开关,外观类
public class Console {
private Equipment camera = new Camera();
private Equipment light = new Light();
private Equipment sensor = new Sensor();
private Equipment alarm = new Alarm();
public void turnOnAll() {
camera.turnOn();
light.turnOn();
sensor.turnOn();
alarm.turnOn();
}
public void turnOffAll() {
camera.turnOff();
light.turnOff();
sensor.turnOff();
alarm.turnOff();
}
public void turnOnAlarm() {
alarm.turnOn();
}
public void turnOffAlarm() {
alarm.turnOff();
}
public void turnOnCamera() {
camera.turnOn();
}
public void turnOffCamera() {
camera.turnOff();
}
public void turnOnLight() {
light.turnOn();
}
public void turnOffLight() {
light.turnOff();
}
public void turnOnSensor() {
sensor.turnOn();
}
public void turnOffSensor() {
sensor.turnOff();
}
}
2.2 子系统角色(Alarm、Camera、Light、Sensor)
package facade.securitySystem;
//子系统报警
public class Alarm implements Equipment {
@Override
public void turnOn() {
// TODO 自动生成的方法存根
System.out.println("打开警报器");
}
@Override
public void turnOff() {
// TODO 自动生成的方法存根
System.out.println("关闭警报器");
}
}
package facade.securitySystem;
//子系统录像机
public class Camera implements Equipment {
@Override
public void turnOn() {
// TODO 自动生成的方法存根
System.out.println("打开录像机");
}
@Override
public void turnOff() {
// TODO 自动生成的方法存根
System.out.println("关闭录像机");
}
}
package facade.securitySystem;
//子系统灯
public class Light implements Equipment {
@Override
public void turnOn() {
// TODO 自动生成的方法存根
System.out.println("打开电灯");
}
@Override
public void turnOff() {
// TODO 自动生成的方法存根
System.out.println("关闭电灯");
}
}
package facade.securitySystem;
//子系统传感器
public class Sensor implements Equipment {
@Override
public void turnOn() {
// TODO 自动生成的方法存根
System.out.println("打开传感器");
}
@Override
public void turnOff() {
// TODO 自动生成的方法存根
System.out.println("关闭传感器");
}
}
2.3 main方法实现外观模式(Security)
package facade.securitySystem;
//保安
public class Security {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Console console = new Console();
console.turnOnAll();
console.turnOffAll();
console.turnOnAlarm();
console.turnOffAlarm();
}
}