references:
https://github.com/iluwatar/java-design-patterns/tree/master/facade
facade这个单词的字面意思是“正面、外观”
举一个现实中的例子来更容易去理解这个模式的意图:
如果我问你金矿是怎么运作的,你可能会说,这很简单,矿工下去把金子挖出来就完事儿了
你这么说是因为你只看到了金矿向外暴露的样子
实际上金矿内部很复杂,想挖出金子还需要做很多其他的工作
==通过一个简单的接口来使用一个复杂的系统就是facade==
换句话说,Facade模式为一个复杂的系统提供了一个简单的接口
引用维基百科上的话,facade是一个对象,它为更大的代码体(比如类库)提供简化的接口
本示例的背景是矿工挖金矿
在程序的入口函数中,只有几行代码:
package com.iluwatar.facade;
public class App {
public static void main(String[] args) {
var facade = new DwarvenGoldmineFacade();
facade.startNewDay();
facade.digOutGold();
facade.endDay();
}
}
在获取到facade对象之后,只调用了三个方法
就像上面说过的,你只看到了矿工下去挖矿,然后金子被运出来,你并不了解内部的运作方式,正如主方法中调用的这三个方法:开始新的一天、挖金子、结束
facade为你隐藏了内部实现,你不需要关心他是怎么开始的新的一天,怎么挖的金子,怎么结束的一天,你只需要使用就行了
facade切断了终端用户与金矿子系统的依赖
在本例中,金矿子系统就是抽象类DwarvenMineWorker
package com.iluwatar.facade;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class DwarvenMineWorker {
public void goToSleep() {
LOGGER.info("{} goes to sleep.", name());
}
public void wakeUp() {
LOGGER.info("{} wakes up.", name());
}
public void goHome() {
LOGGER.info("{} goes home.", name());
}
public void goToMine() {
LOGGER.info("{} goes to the mine.", name());
}
private void action(Action action) {
switch (action) {
case GO_TO_SLEEP:
goToSleep();
break;
case WAKE_UP:
wakeUp();
break;
case GO_HOME:
goHome();
break;
case GO_TO_MINE:
goToMine();
break;
case WORK:
work();
break;
default:
LOGGER.info("Undefined action");
break;
}
}
/**
* Perform actions.
*/
public void action(Action... actions) {
Arrays.stream(actions).forEach(this::action);
}
public abstract void work();
public abstract String name();
enum Action {
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
}
}
注意这段代码:
Arrays.stream(actions).forEach(this::action);
很明显,这段代码用到了昨天学习的函数式编程的思想
上面的代码相当于:
Arrays.stream(actions).forEach((action) -> this.action(action));
只不过是遍历方式简化了许多,再加上lambda表达式的简写,一眼看上去可能会不理解
定义完上面的矮人矿工抽象类之后,接着需要编写三个实体类:隧道挖掘工、矿工、运输工
每个实体类都会实现work()
方法和name()
方法,后者不重要,只是用来在演示的时候提供提示信息
不同的矿工拥有不同的work()
实现,这些方法会在DwarvenGoldmineFacade
类中被调用
这个设计模式其实还算比较好理解,就是复杂系统的内部实现对于用户是透明的,就像使用计算机,它只呈献给用户一个UI,但是具体内部实现原理是与用户隔绝的