JAVA设计模式—Facade外观

本文的设计模式列表来源于github上人气比较高的iluwatar/java-design-patterns,包含了23种经典设计模式和很多实际应用中涉及到的模式。

文中涉及到的示例代码可能只抽取了部分进行讲解,如果有本地模拟需求,请参考源码。

“设计模式是程序员在设计应用程序时能够解决场景问题的最佳实现,通过经测试和验证的开发范例,可以提高开发效率。重用设计模式,可有效避免可能因细微问题而导致的重大隐患,同时有助于提升熟悉设计模式的编码人员和架构师对代码的可读性。”

作用

外观模式Facade),为子系统中的各类(或接口、方法)提供更加统一的接口。Facade模式定义了更高级别的接口,使得子系统更易于使用。

适用性

  1. 为复杂的子系统提供一个更简单的接口。子系统通常会随着系统的发展变得更加复杂,Facade可以为子系统提供一个简单的默认视图,来满足大部分的客户端调用;
  2. 当客户端和抽象实现类存在较多依赖关系时,可以引入外观模式,将被客户端依赖的子系统与其他子系统分离,从而提高子系统的独立性和可移植性。
  3. 当需要对子系统进行分层管理,可以通过外观模式,为每个层的子系统定义一个切入点,当不同层的子系统存在依赖时,则可以简化各层之间的依赖关系。

典型用例

代码示例

以挖矿游戏为例。挖矿由隧道挖掘工、矿工、运输工协同完成,协同工作属于子系统,外部只关心挖矿的最终结果。

  1. 定义抽象矿工类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    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;
    }
    }
    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
    }
    }
  2. 定义隧道挖掘子系统

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class DwarvenTunnelDigger extends DwarvenMineWorker {
    @Override
    public void work() {
    LOGGER.info("{} creates another promising tunnel.", name());
    }
    @Override
    public String name() {
    return "Dwarven tunnel digger";
    }
    }
  3. 定义挖矿子系统

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class DwarvenGoldDigger extends DwarvenMineWorker {
    @Override
    public void work() {
    LOGGER.info("{} digs for gold.", name());
    }
    @Override
    public String name() {
    return "Dwarf gold digger";
    }
    }
  4. 定义运输子系统

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class DwarvenCartOperator extends DwarvenMineWorker {
    @Override
    public void work() {
    LOGGER.info("{} moves gold chunks out of the mine.", name());
    }
    @Override
    public String name() {
    return "Dwarf cart operator";
    }
    }
  5. 外观实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class DwarvenGoldmineFacade {
    private final List<DwarvenMineWorker> workers;
    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);
    }
    }
    }

类图