🔍目的
為一個子系統中的一系列接口提供一個統一的接口。外觀定義了一個更高級別的接口以便子系統更容易使用。
🔍解釋
真實世界例子
一個金礦是怎么工作的?“嗯,礦工下去然后挖金子!”你說。這是你所相信的因為你在使用一個金礦對外提供的一個簡單接口,在內部它要卻要做很多事情。這個簡單的接口對復雜的子系統來說就是一個外觀。
通俗描述
外觀模式為一個復雜的子系統提供一個簡單的接口。
維基百科
外觀是為很大體量的代碼(比如類庫)提供簡單接口的一種對象。
程序示例
使用上面金礦的例子。這里我們有矮人的礦工等級制度。
@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 {@Overridepublic void work() {LOGGER.info("{} creates another promising tunnel.", name());}@Overridepublic String name() {return "Dwarven tunnel digger";}
}@Slf4j
public class DwarvenGoldDigger extends DwarvenMineWorker {@Overridepublic void work() {LOGGER.info("{} digs for gold.", name());}@Overridepublic String name() {return "Dwarf gold digger";}
}@Slf4j
public class DwarvenCartOperator extends DwarvenMineWorker {@Overridepublic void work() {LOGGER.info("{} moves gold chunks out of the mine.", name());}@Overridepublic String name() {return "Dwarf cart operator";}
}
創建外觀類來進行操縱這些礦工:
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));}
}
使用外觀:
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來簡化交互過程。?
希望本文能夠幫助讀者更深入地理解外觀模式,并在實際項目中發揮其優勢。謝謝閱讀!
希望這份博客草稿能夠幫助到你。如果有其他需要修改或添加的地方,請隨時告訴我。