《设计模式》外观模式
定义:
- 外观模式(Facade) 也叫门面模式,该模式通过定义一个高层接口,为多个复杂的子系统提供一个一致性的访问接口,而使这些子系统更加容易使用。
- 一致性的访问接口旨在屏蔽子系统的细节,使得调用方只需要调用一致性的接口,而无需关心子系统的内部细节,降低应用程序的复杂度,提高可维护性。
外观模式的主要角色:
- 外观类(Facade):为多个子系统对外提供一个共同的接口。
- 子系统集合:处理外观类对象指派的任务,是功能的实际提供方。
- 外观模式的注意事项:
外观模式对外屏蔽了子系统的内部细节,降低了客户端对子系统的使用复杂性。
当系统需要进行分层设计时,可以考虑使用外观模式。
当一个遗留的大型系统变得难以维护和扩展时,考虑为新系统开发一个 Facade 类,来提供遗留系统的清晰简单的接口,让新系统和 Facade 类交互,提高复用性。
合理使用外观模式,可以帮助更好的划分访问层次。
外观模式不符合开闭原则,修改起来比较麻烦。
外观模式的使用场景:
在对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
外观模式的原理类图如下所示:
案例背景:
小明的爷爷每天晚上睡觉前需要使用房间里不同电器的遥控器将空调、电视机、电灯、加湿器、自动化窗帘一个个关掉,每天早上醒来还需要将这些电器自动化设备一个个打开,爷爷感觉非常麻烦,因此孝顺的小明能帮他做一个工具,能够实现一键控制,打开或者关掉房间的这些设备。
小明设计的类图如下所示:
Client
类:
public class Client { public static void main(String[] args) { Facade facade = new Facade(); System.out.println("----------每天早起第一件事:打开房间内的电器------------------"); facade.turnOn(); System.out.println("----------每天睡前最后一件事:关闭房间内的电器----------------"); facade.turnOff(); } }
Facade
类:
public class Facade { private AirConditioner airConditioner; private TV tv; private Light light; private Humidifier humidifier; public Facade() { airConditioner = new AirConditioner(); tv = new TV(); light = new Light(); humidifier = new Humidifier(); } public void turnOn() { airConditioner.turnOn(); tv.turnOn(); light.turnOn(); humidifier.turnOn(); } public void turnOff() { airConditioner.turnOff(); tv.turnOff(); light.turnOff(); humidifier.turnOff(); } }
AirConditioner
类:
public class AirConditioner { public void turnOn() { System.out.println("打开了空调...."); } public void turnOff() { System.out.println("关闭了空调...."); } }
TV
类:
public class TV { public void turnOn() { System.out.println("打开了电视...."); } public void turnOff() { System.out.println("关闭了电视...."); } }
Light
类:
public class Light { public void turnOn() { System.out.println("打开了电灯...."); } public void turnOff() { System.out.println("关闭了电灯...."); } }
Humidifier
类:
public class Humidifier { public void turnOn() { System.out.println("打开了加湿器...."); } public void turnOff() { System.out.println("关闭了加湿器...."); } }
外观模式在 Mybatis 框架中的应用:
Configuration
类
public class Configuration { //... public MetaObject newMetaObject(Object object) { return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory, this.reflectorFactory); } //... }
MetaObject
类
public class MetaObject { private final Object originalObject; private final ObjectWrapper objectWrapper; private final ObjectFactory objectFactory; private final ObjectWrapperFactory objectWrapperFactory; private final ReflectorFactory reflectorFactory; private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) { this.originalObject = object; this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; this.reflectorFactory = reflectorFactory; if (object instanceof ObjectWrapper) { this.objectWrapper = (ObjectWrapper)object; } else if (objectWrapperFactory.hasWrapperFor(object)) { this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object); } else if (object instanceof Map) { this.objectWrapper = new MapWrapper(this, (Map)object); } else if (object instanceof Collection) { this.objectWrapper = new CollectionWrapper(this, (Collection)object); } else { this.objectWrapper = new BeanWrapper(this, object); } } public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) { return object == null ? SystemMetaObject.NULL_META_OBJECT : new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory); } //... }
角色类图如下所示: