设计原则
迪米特法则:应当使得软件的不同对象彼此之间尽量“老死不相往来”,降低系统维护成本
意图
- 提供了一个统一的接口,用来访问子系统中的一群接口
- Facade定义了一个高层接口,让子系统更容易使用
动机
- 将一个系统划分成为若干个子系统有利于降低系统的复杂性
- 设计目标是使子系统间的通信和相互依赖关系达到最小
- 途径之一是就是引入一个 外观对象
- 它为子系统中较一般的设施提供了一个单一而简单的界面
适用性
- 为复杂子系统提供一个简单接口,定义一个高层接口,使子系统更加容易使用
- 解除客户程序与抽象类具体实现部分的依赖性,提高子系统的独立性和可移植性
- 当需要构建层次结构的子系统时,使用Facade模式定义每层的入口点。如果子系统间相互依赖, 他们仅通过Facade进行通讯,简化了它们之间的依赖关系
结构和参与者
- Facade(门面角色)
知道哪些子系统类负责处理请求
并将客户的请求代理给适当的子系统对象 - Subsystem (子系统角色 )
实现子系统的功能
处理由Facade 对象指派的任务
没有Facade的任何相关信息
效果
- 对客户端屏蔽子系统组件,减少客户端使用对象数目
- 实现了子系统与客户之间松耦合的关系,使得子系统组件的变化不会影响到客户
- 不限制客户应用子系统类
代码示例
public class Airport {
public void bookTicket(String from, String to) {
System.out.println("订购了从" + from + "到" + to + "的机票");
}
}
public class Restaurant {
public void reserve(int num) {
System.out.println("订了一桌" + num + "个人的酒席");
}
}
public class Hotel {
public void reserve(int days) {
System.out.println("订了" + days + "天的房间");
}
}
public class Chauffeur {
public void drive(String to) {
System.out.println("司机开车去" + to);
}
}
// 秘书
public class Secretary {
private Chauffeur chauffeur = new Chauffeur();
private Hotel hotel = new Hotel();
private Restaurant restaurant = new Restaurant();
private Airport airport = new Airport();
// 安排出差
public void trip(String to, int days) {
airport.bookTicket("青岛", to);
chauffeur.drive("机场");
hotel.reserve(days);
}
// 安排饭局
public void repast(int num) {
restaurant.reserve(num);
chauffeur.drive("酒店");
}
}
public class Boss {
public static void main(String[] args) {
Secretary s = new Secretary();
System.out.println("老板告诉秘书要到上海出差10天");
s.trip("上海", 10);
System.out.println("---------------------");
System.out.println("老板告诉秘书要请8个人吃饭");
s.repast(8);
}
}
评价
- 优点
子系统的类不识别外观
使用子系统的功能更简单
客户类和子系统实现松耦合 - 缺点
增加了附加方法调用
子系统中类的功能受到外观的限制
封装组件接口改变导致外观跟着改变
依然允许直接调用