一、定义
The Facade Pattern provides a unified interface to a
set of interfaces in a subsytem. Facade defines a higher-
level interface that makes the subsystem easier to use.
门面模式为子系统中一系列的接口提供了一个统一接口。门面模式定义了更高级的接口,使得子系统更加容易使用。
门面模式也是一个容易理解的模式,就是把一系列的操作都整合到一个接口里,子系统外面的Client只需要与这个统一的接口打交道即可,因此它是为简化子系统的使用而设计的。为什么要这么设计呢?面向对象设计原则中有一个迪米特法则(最少知识法则),也就是一个类或方法只与自己最熟悉的朋友打交道,什么才是最熟悉的朋友?大体如下:
- 对象本身的方法(方法所具有的功能);
- 一个方法中的参数(参数所具有的功能);
- 任何地方创建的对象(对象所具有的功能);
- 对象通过“has-a”的属性(该属性所具有的功能)
举几个栗子,没有使用迪米特法则的代码:
class Thermometer {
float currentTemperature;
public float getTemperature() {
return currentTemperature;
}
}
class Station {
Thermometer thermometer;
Thermometer getThermometer(){
return thermometer;
}
}
public class Test{
Station station;
public float getTemp() {
Thermometer thermometer = station.getThermometer();
return thermometer.getTemperature();
}
}
使用迪米特法则后,减少不必要的类之间的耦合:
class Thermometer {
float currentTemperature;
public float getTemperature() {
return currentTemperature;
}
}
class Station {
Thermometer thermometer;
Thermometer getThermometer(){
return thermometer;
}
public float getTemperature() {
return thermometer.getTemperature();
}
}
public class Test{
Station station;
public float getTemp() {
return station.getTemperature();
}
}
没使用迪米特法则的代码:
public House {
WeatherStation station;
// other methods and constructor
public float getTemp() {
return station.getThermometer().getTemperature();
}
}
使用了迪米特法则,通过增加一个方法和传递参数实现:
public House {
WeatherStation station;
// other methods and constructor
public float getTemp() {
Thermometer thermometer = station.getThermometer();
return getTempHelper(thermometer);
}
public float getTempHelper(Thermometer thermometer) {
return thermometer.getTemperature();
}
}
二、实例
有一台家务机器人,她每天要完成叫主人起床、准备早餐、送行、洗碗、迎接主人回家、准备晚餐、洗碗等任务,其中,叫主人起床需要用到闹钟功能,准备早餐和晚餐需要用到营养师功能,洗碗需要用到洗碗功能,送行和迎接主人回家需要用到打招呼功能…
public class Robot {
Clock clock;
Dietitian dietitian;
WashDishes washDishes;
Welcome welcome;
public Robot(Clock clock, Dietitian dietitian, WashDishes washDishes, Welcome welcome) {
this.clock = clock;
this.dietitian = dietitian;
this.washDishes = washDishes;
this.welcome = welcome;
}
public void doMorningTasks() {
clock.alarm();
dietitian.prepareBreakfast();
welcome.seeoff();
washDishes.washDishes();
}
public void doEveningTasks() {
welcome.welcomeBack();
dietitian.prepareDinner();
washDishes.washDishes();
}
public static void main(String[] args) {
Robot robot=new Robot(new Clock(), new Dietitian(), new WashDishes(), new Welcome());
System.out.println("In the morning:");
robot.doMorningTasks();
System.out.println("In the evening:");
robot.doEveningTasks();
}
}
class Clock {
public void alarm() {
System.out.println("到点了,请起床!");
}
}
class Dietitian {
public void prepareBreakfast() {
System.out.println("准备营养早餐");
}
public void prepareDinner() {
System.out.println("准备丰盛晚餐");
}
}
class WashDishes {
public void washDishes() {
System.out.println("洗碗");
}
}
class Welcome {
public void seeoff() {
System.out.println("路上慢走!");
}
public void welcomeBack() {
System.out.println("欢迎回家!");
}
}
运行结果:
In the morning:
到点了,请起床!
准备营养早餐
路上慢走!
洗碗
In the evening:
欢迎回家!
准备丰盛晚餐
洗碗
类图:
分析:上述类图就相当于一个子系统,外面的人只需要控制Robot机器人即可,简化了调用方的操作,符合迪米特法则,这就是门面模式。