什么是外观模式
外观模式是指为子系统中的一组接口提供一个统一的入口,外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。
外观模式是迪米特法则的具体实现,为子系统的外部与其内部的通信通过一个统一的外观类进行,外观类将客户端与子系统的内部复杂性分隔开,客户端只需要与外观类交互。
外观模式包含以下几个角色:
Facade(外观角色):在客户端调用他的方法,在外观角色中可以知道相关子系统的功能与职责,将客户端过来的请求传递到对应的子系统中。
SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以是一个单独的类,也可以是一个类的集合,他实现了子系统的功能。每一个子系统都可以被客户端直接调用,或者被外观角色调用。
外观模式的优缺点
优点
- 对客户端隐藏了子系统组件,减少客户端需要处理的内容,并使得子系统使用起来更加容易。
- 实现了子系统与客户端之间的松耦合,子系统的变化不会影响到客户端,只需要修改外观类即可。
- 一个子系统的修改不会影响其他子系统。
缺点
- 不能很好的限制客户端直接使用子系统类,如果做太多限制则减少了灵活性。
- 增加新的子系统需要修改外观类,违背开闭原则。
外观模式的应用场景
- 当为访问一系列复杂的子系统提供一个简单入口时。
- 客户端与很多子系统之间存在很大依赖时。
- 在层次化结构中,可以使用外观模式定义每一层的入口,层与层之前不直接联系,通过外观类建立连接,降低层与层之间的耦合。
外观模式的案例
// 下单外观类
public class OrderFacade {
private ChooseProduct chooseProduct;
private PayForProduct payForProduct;
private WaitingForDelivery waitingForDelivery;
public OrderFacade() {
chooseProduct = new ChooseProduct();
payForProduct = new PayForProduct();
waitingForDelivery = new WaitingForDelivery();
}
public void buyProduct() {
chooseProduct.chooseOne();
payForProduct.pay();
waitingForDelivery.delivery();
}
}
// 产品子系统
public class ChooseProduct {
public void chooseOne() {
System.out.println("选择一个产品");
}
}
// 支付子系统
public class PayForProduct {
public void pay() {
System.out.println("为产品支付");
}
}
// 物流子系统
public class WaitingForDelivery {
public void delivery() {
System.out.println("等待产品发货");
}
}
外观模式在源码中的应用
org.apache.ibatis.session.Configuration
public class Configuration {
// 调用 MetaObject 子系统
public MetaObject newMetaObject(Object object) {
return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}