JavaでのMediatorデザインパターン

Mediatorデザインパターンは、行動デザインパターンの一つであり、したがってオブジェクトの振る舞いに関連しています。Mediatorデザインパターンは、システム内の異なるオブジェクト間で中央集権のコミュニケーション媒体を提供するために使用されます。

Mediatorデザインパターン

GoFによれば、Mediatorパターンの意図は:

異なるオブジェクト間の相互作用とコミュニケーションの方法をカプセル化することによって、緩い結合を可能にし、各オブジェクトセットのアクションが互いに独立して変化できるようにします。

Mediatorデザインパターンは、エンタープライズアプリケーションにおいて非常に役立ちます。ここでは複数のオブジェクトが互いにやり取りしている状況です。オブジェクトが直接やり取りする場合、システムコンポーネントは互いに強く結合され、保守コストが高く、拡張が難しくなります。Mediatorパターンは、オブジェクト間の通信の仲介を提供し、オブジェクト間の緩やかな結合を実現するのに役立ちます。エアトラフィックコントローラは、異なるフライト間の通信のために空港管制室が仲介者として機能する優れた例です。Mediatorはオブジェクト間のルーターとして機能し、通信手段を提供するための独自のロジックを持つことがあります。お互いに通信するシステムオブジェクトはColleaguesと呼ばれます。通常、インターフェースまたは抽象クラスが通信の契約を提供し、その後、Mediatorの具体的な実装があります。この例では、ユーザーがグループチャットを行えるようなチャットアプリケーションを実装してみます。各ユーザーは名前で識別され、メッセージの送受信が可能です。任意のユーザーが送信したメッセージは、グループ内の他のすべてのユーザーに受信されるべきです。

Mediatorパターンのインターフェース

ますます、私たちは具体的なMediatorの契約を定義するMediatorインターフェースを作成します。 ChatMediator.java

package com.journaldev.design.mediator;

public interface ChatMediator {

	public void sendMessage(String msg, User user);

	void addUser(User user);
}

Mediator Pattern Colleague Interface

ユーザーはメッセージを送受信できるため、User インターフェースまたは抽象クラスを持つことができます。私は以下のように User を抽象クラスとして作成しています。User.java

package com.journaldev.design.mediator;

public abstract class User {
	protected ChatMediator mediator;
	protected String name;
	
	public User(ChatMediator med, String name){
		this.mediator=med;
		this.name=name;
	}
	
	public abstract void send(String msg);
	
	public abstract void receive(String msg);
}

User がメディエーターオブジェクトへの参照を持っていることに注意してください。これは異なるユーザー間の通信に必要です。

Concrete Mediator

これで具体的なメディエータークラスを作成します。これにはグループ内のユーザーのリストが含まれ、ユーザー間の通信のためのロジックを提供します。ChatMediatorImpl.java

package com.journaldev.design.mediator;

import java.util.ArrayList;
import java.util.List;

public class ChatMediatorImpl implements ChatMediator {

	private List users;
	
	public ChatMediatorImpl(){
		this.users=new ArrayList<>();
	}
	
	@Override
	public void addUser(User user){
		this.users.add(user);
	}
	
	@Override
	public void sendMessage(String msg, User user) {
		for(User u : this.users){
			//メッセージはそれを送信したユーザーによって受信されないようにする必要があります
			if(u != user){
				u.receive(msg);
			}
		}
	}

}

Mediator Design Pattern Concrete Colleague

これでクライアントシステムで使用される具体的な User クラスを作成できます。UserImpl.java

package com.journaldev.design.mediator;

public class UserImpl extends User {

	public UserImpl(ChatMediator med, String name) {
		super(med, name);
	}

	@Override
	public void send(String msg){
		System.out.println(this.name+": Sending Message="+msg);
		mediator.sendMessage(msg, this);
	}
	@Override
	public void receive(String msg) {
		System.out.println(this.name+": Received Message:"+msg);
	}

}

send() メソッドがメディエーターを使用してメッセージをユーザーに送信しており、それがメディエーターによってどのように処理されるかはわかりません。

メディエーターパターンの例 クライアントプログラムのコード

このチャットアプリケーションを単純なプログラムでテストしましょう。メディエーターを作成し、ユーザーをグループに追加し、ユーザーの一人がメッセージを送信します。ChatClient.java

package com.journaldev.design.mediator;

public class ChatClient {

	public static void main(String[] args) {
		ChatMediator mediator = new ChatMediatorImpl();
		User user1 = new UserImpl(mediator, "Pankaj");
		User user2 = new UserImpl(mediator, "Lisa");
		User user3 = new UserImpl(mediator, "Saurabh");
		User user4 = new UserImpl(mediator, "David");
		mediator.addUser(user1);
		mediator.addUser(user2);
		mediator.addUser(user3);
		mediator.addUser(user4);
		
		user1.send("Hi All");
		
	}

}

クライアントプログラムは非常にシンプルであり、メッセージの処理方法やメディエーターがユーザーを取得しているかどうかはわかりません。メディエーターパターンの例プログラムの出力は次のとおりです:

Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All

メディエーターパターン クラスダイアグラム

JDKにおけるメディエーターパターンの例

Mediator デザインパターンの重要なポイント

  • Mediator パターンは、オブジェクト間の通信ロジックが複雑な場合に役立ちます。通信ロジックを管理する中央の通信ポイントを持つことができます。
  • Java Message Service(JMS)は、Observer パターンとともに Mediator パターンを使用して、アプリケーションが他のアプリケーションにデータを購読および公開できるようにします。
  • Mediator パターンを単なる疎結合を達成するためだけに使用すべきではありません。なぜなら、中央の数が増えると、それらを維持することが難しくなるからです。

これで Mediator デザインパターンとその Java での実装についての説明は以上です。

Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java