Javaにおけるファサードパターン:複雑なシステムインターフェースを簡素化する
ファサードデザインパターンの意図
ファサードデザインパターンは、サブシステム内の一連のインターフェースに対して統一されたインターフェースを提供します。このJavaデザインパターンは、複雑なシステムインタラクションを簡素化します。
ファサードパターンの詳細な説明と現実世界の例
現実世界の例
複数のコンポーネント(DVDプレーヤー、プロジェクター、サラウンドサウンドシステム、照明)を備えたホームシアターシステムを想像してみてください。各コンポーネントには、多数の機能と設定を備えた複雑なインターフェースがあります。ホームシアターシステムの使用を簡素化するために、リモコン(ファサード)が提供されています。リモコンは、「映画を再生」、「停止」、「一時停止」、「音量アップ/ダウン」などのシンプルなボタンを備えた統一されたインターフェースを提供します。これらのボタンは内部でさまざまなコンポーネントと通信し、コンポーネント間のやり取りを管理します。これにより、各コンポーネントの詳細な操作を理解しなくても、システムを簡単に使用できます。
平易な言葉で
ファサードパターンは、複雑なサブシステムに対して簡素化されたインターフェースを提供します。
Wikipediaによると
ファサードとは、クラスライブラリなど、より大きなコード本体に対して簡素化されたインターフェースを提供するオブジェクトです。
Javaにおけるファサードパターンのプログラム例
これは、金鉱のシナリオにおけるファサードデザインパターンの例であり、Javaファサードが複雑な操作をどのように効率化できるかを示しています。
金鉱はどのように機能するのでしょうか?「ええと、鉱夫がそこに行って金を掘るんだ!」と言うでしょう。それはあなたがそう信じているのは、あなたが金鉱が外部に提供するシンプルなインターフェースを使っているからであり、内部ではそれを実現するために多くのことをしなければなりません。複雑なサブシステムへのこのシンプルなインターフェースがファサードです。
ここでは、ドワーフの鉱山労働者の階層があります。まず、基本クラス DwarvenMineWorker
があります。
@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
}
}
次に、具象ドワーフクラス DwarvenTunnelDigger
、DwarvenGoldDigger
、および DwarvenCartOperator
があります。
@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";
}
}
これらの金鉱労働者全員を操作するために、DwarvenGoldmineFacade
があります。
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));
}
}
では、ファサードを使用してみましょう。
public static void main(String[] args) {
var facade = new DwarvenGoldmineFacade();
facade.startNewDay();
facade.digOutGold();
facade.endDay();
}
プログラムの出力
06:07:20.676 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf gold digger wakes up.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf gold digger goes to the mine.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf cart operator wakes up.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf cart operator goes to the mine.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarven tunnel digger wakes up.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarven tunnel digger goes to the mine.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenGoldDigger -- Dwarf gold digger digs for gold.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenCartOperator -- Dwarf cart operator moves gold chunks out of the mine.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenTunnelDigger -- Dwarven tunnel digger creates another promising tunnel.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf gold digger goes home.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf gold digger goes to sleep.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf cart operator goes home.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarf cart operator goes to sleep.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarven tunnel digger goes home.
06:07:20.678 [main] INFO com.iluwatar.facade.DwarvenMineWorker -- Dwarven tunnel digger goes to sleep.
Javaでファサードパターンを使用する場合
次の場合にJavaでファサードパターンを使用します。
- 複雑なサブシステムにシンプルなインターフェースを提供したい場合。
- サブシステムがより複雑になり、複数のクラスに依存しているが、ほとんどのクライアントは機能の一部のみを必要とする場合。
- サブシステムを階層化する必要がある場合。ファサードを使用して、各サブシステムレベルへのエントリポイントを定義します。
- Java開発で依存関係を減らし、コードの可読性を向上させたい場合。
ファサードパターンJavaチュートリアル
- Javaにおけるファサードデザインパターン (DigitalOcean)
- ファサード (Refactoring Guru)
- ファサードメソッドデザインパターン (GeekforGeeks)
- デザインパターン - ファサードパターン (TutorialsPoint)
Javaにおけるファサードパターンの現実世界の応用
- java.net.URLやjavax.faces.context.FacesContextなどのJavaライブラリは、ファサードを使用して複雑な基盤となるクラスを簡素化します。
- 多くのJavaフレームワークでは、ファサードは、より複雑な基盤となるコード構造に対してよりシンプルなインターフェースを提供することにより、APIの使用を簡素化するために使用されます。
ファサードパターンの利点とトレードオフ
メリット
Javaでのファサードデザインパターンの実装
- クライアントをサブシステムコンポーネントから分離し、使用を容易にし、依存関係を減らします。
- サブシステムとそのクライアント間の疎結合を促進します。
- 多くの場合、複雑なシステムのAPIを簡素化します。
トレードオフ
- ファサードは、正しく実装されていない場合、アプリのすべてのクラスに結合されたゴッドオブジェクトになる可能性があります。
関連するJavaデザインパターン
- アダプター: ファサードは統一されたインターフェースを提供しますが、アダプターは2つの既存のインターフェースを連携させます。
- メディエーター: ファサードはサブシステムへのよりシンプルなインターフェースを定義しますが、メディエーターはオブジェクト間の複雑な通信と制御を集中化します。