外观模式(Facade DP),提供了一个统一接口,来访问子系统中的一群接口。定义高层接口,让子系统更容易使用。
外观这个名字,可以这么理解:假设你要开机,机箱的外观上只有一个开机按钮,但是你按下去之后,机箱里面有一系列的运作,最后实现开机。也就是说,这个外观让一些操作简单化,有点一键端的感觉。
不过这个说法也有点问题,因为外观模式不会掩盖内部的结构,如果你想要直接调用子系统的底层操作也是可以的。这么理解的话,就好比机箱的侧盖没有关上,你仍然可以通过操作一些电路来实现开机,面板上的开机按钮只是提供了一个简化使用的选项。
代码:
现在有一个矮人金矿系统,里面有各种工人。
矮人金矿工人基类:
/**
*
* DwarvenMineWorker is one of the goldmine subsystems.
*
*/
public abstract class DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenMineWorker.class);
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) {
for (Action action : actions) {
action(action);
}
}
public abstract void work();
public abstract String name();
static enum Action {
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
}
}
/**
*
* DwarvenCartOperator is one of the goldmine subsystems.
*
*/
public class DwarvenCartOperator extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenCartOperator.class);
@Override
public void work() {
LOGGER.info("{} moves gold chunks out of the mine.", name());
}
@Override
public String name() {
return "Dwarf cart operator";
}
}
/**
*
* DwarvenGoldDigger is one of the goldmine subsystems.
*
*/
public class DwarvenGoldDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenGoldDigger.class);
@Override
public void work() {
LOGGER.info("{} digs for gold.", name());
}
@Override
public String name() {
return "Dwarf gold digger";
}
}
/**
*
* DwarvenTunnelDigger is one of the goldmine subsystems.
*
*/
public class DwarvenTunnelDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenTunnelDigger.class);
@Override
public void work() {
LOGGER.info("{} creates another promising tunnel.", name());
}
@Override
public String name() {
return "Dwarven tunnel digger";
}
}
矮人金矿外观:
/**
*
* DwarvenGoldmineFacade provides a single interface through which users can operate the subsystems.
*
* This makes the goldmine easier to operate and cuts the dependencies from the goldmine user to the
* subsystems.
*
*/
public class DwarvenGoldmineFacade {
private final List<DwarvenMineWorker> workers;
/**
* Constructor
*/
public DwarvenGoldmineFacade() {
workers = new ArrayList<>();
workers.add(new DwarvenGoldDigger());
workers.add(new DwarvenCartOperator());
workers.add(new DwarvenTunnelDigger());
}
public void startNewDay() {
makeActions(workers, DwarvenMineWorker.Action.WAKE_UP, DwarvenMineWorker.Action.GO_TO_MINE);
}
public void digOutGold() {
makeActions(workers, DwarvenMineWorker.Action.WORK);
}
public void endDay() {
makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP);
}
private static void makeActions(Collection<DwarvenMineWorker> workers,
DwarvenMineWorker.Action... actions) {
for (DwarvenMineWorker worker : workers) {
worker.action(actions);
}
}
}
把子系统的接口统一起来,这样只需要很少的代码就能使金矿运作:
public static void main(String[] args) {
DwarvenGoldmineFacade facade = new DwarvenGoldmineFacade();
facade.startNewDay();
facade.digOutGold();
facade.endDay();
}