什么是外观(Facade)模式?
当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这时如果系统内部发生改变,客户端也要跟着改变,这违背了“开闭原则”,也违背了“迪米特法则”,所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式的目标。
外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
这种模式隐藏了更大系统的复杂性,并提供了一个更简单的系统。
例子
在本例中,Facade是({@link dwarvengoldminefaccade}),它为金矿子系统提供了一个更简单的接口。
public class App {
/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
var facade = new DwarvenGoldmineFacade();
facade.startNewDay();
facade.digOutGold();
facade.endDay();
}
}
public class DwarvenGoldmineFacade {
private final List<DwarvenMineWorker> workers;
/**
* Constructor.
*/
public DwarvenGoldmineFacade() {
workers = List.of(
new DwarvenGoldDigger(),
new DwarvenCartOperator(),
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
) {
workers.forEach(worker -> worker.action(actions));
}
}
/**
* 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) {
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
}
}
/**
* 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(矮人隧道挖掘机)";
}
}