【设计模式】JAVA Design Patterns——Facade(外观模式)

🔍目的


为一个子系统中的一系列接口提供一个统一的接口。外观定义了一个更高级别的接口以便子系统更容易使用。

🔍解释


真实世界例子

一个金矿是怎么工作的?"嗯,矿工下去然后挖金子!"你说。这是你所相信的因为你在使用一个金矿对外提供的一个简单接口,在内部它要却要做很多事情。这个简单的接口对复杂的子系统来说就是一个外观。

通俗描述

外观模式为一个复杂的子系统提供一个简单的接口。

维基百科

外观是为很大体量的代码(比如类库)提供简单接口的一种对象。

程序示例

使用上面金矿的例子。这里我们有矮人的矿工等级制度。

java 复制代码
@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();
            case WAKE_UP -> wakeUp();
            case GO_HOME -> goHome();
            case GO_TO_MINE -> goToMine();
            case WORK -> work();
            default -> LOGGER.info("Undefined action");
        }
    }

    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
    }
}

@Slf4j
public class DwarvenTunnelDigger extends DwarvenMineWorker {

    @Override
    public void work() {
        LOGGER.info("{} creates another promising tunnel.", name());
    }

    @Override
    public String name() {
        return "Dwarven tunnel digger";
    }
}

@Slf4j
public class DwarvenGoldDigger extends DwarvenMineWorker {

    @Override
    public void work() {
        LOGGER.info("{} digs for gold.", name());
    }

    @Override
    public String name() {
        return "Dwarf gold digger";
    }
}

@Slf4j
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";
    }
}

创建外观类来进行操纵这些矿工:

java 复制代码
public class DwarvenGoldmineFacade {

  private final List<DwarvenMineWorker> workers;

  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));
  }
}

使用外观:

java 复制代码
DwarvenGoldmineFacade facade = new DwarvenGoldmineFacade();
facade.startNewDay();
// Dwarf gold digger wakes up.
// Dwarf gold digger goes to the mine.
// Dwarf cart operator wakes up.
// Dwarf cart operator goes to the mine.
// Dwarven tunnel digger wakes up.
// Dwarven tunnel digger goes to the mine.
facade.digOutGold();
// Dwarf gold digger digs for gold.
// Dwarf cart operator moves gold chunks out of the mine.
// Dwarven tunnel digger creates another promising tunnel.
facade.endDay();
// Dwarf gold digger goes home.
// Dwarf gold digger goes to sleep.
// Dwarf cart operator goes home.
// Dwarf cart operator goes to sleep.
// Dwarven tunnel digger goes home.
// Dwarven tunnel digger goes to sleep.

🔍类图


🔍适用性


使用外观模式

  • 你想为一个复杂的子系统提供一个简单的接口。随着子系统的发展,它们通常会变得更加复杂。多数模式在应用时会导致更多和更少的类。这使子系统更可重用,更易于自定义,但是对于不需要自定义它的客户来说,使用它也变得更加困难。 外观可以提供子系统的简单默认视图,足以满足大多数客户端的需求。只有需要更多可定制性的客户才需要查看外观外的东西(原子系统提供的接口)。
  • 客户端与抽象的实现类之间存在许多依赖关系。 引入外观以使子系统与客户端和其他子系统分离,从而提高子系统的独立性和可移植性。
  • 您想对子系统进行分层。 使用外观来定义每个子系统级别的入口点。 如果子系统是相关的,则可以通过使子系统仅通过其外观相互通信来简化它们之间的依赖性。

🔍Ending

Facade模式通常涉及一个名为Facade的单一类,该类提供了一个高级接口,用于与客户端交互,并将客户端的请求委派给系统内部的一组相关对象。这样,客户端就不需要直接与系统内部的各个组件进行交互,而是通过Facade来简化交互过程。


希望本文能够帮助读者更深入地理解外观模式,并在实际项目中发挥其优势。谢谢阅读!


希望这份博客草稿能够帮助到你。如果有其他需要修改或添加的地方,请随时告诉我。

相关推荐
虫小宝34 分钟前
如何在Java中实现PDF生成
java·开发语言·pdf
Java4ye34 分钟前
Netty 是如何解析 Redis RESP 协议的——请求篇
后端
菜鸡且互啄691 小时前
在线教育平台,easyexcel使用案例
java·开发语言
八月林城2 小时前
JAVA导出数据库字典到Excel
java·数据库·excel
电饭叔3 小时前
《python程序语言设计》2018版第5章第52题利用turtle绘制sin函数
开发语言·python
weixin_452600693 小时前
如何为老化的汽车铅酸电池充电
开发语言·单片机·安全·汽车·电机·电源模块·充电桩
浅念同学3 小时前
算法-常见数据结构设计
java·数据结构·算法
Java资深爱好者3 小时前
如何在std::map中查找元素
开发语言·c++
YCCX_XFF214 小时前
ImportError: DLL load failed while importing _imaging: 操作系统无法运行 %1
开发语言·python
哥廷根数学学派5 小时前
基于Maximin的异常检测方法(MATLAB)
开发语言·人工智能·深度学习·机器学习