cheka.jp 超不定期で更新する写真達。お口直しにどうぞ。

[写経] PHPで学ぶデザインパターン15

— 注意 —
PHPによるデザインパターンの写経ですが、まんま書くと問題があるのでアウトプットとして備忘録メモです

Interpreterが先でしたが、活用パターンが見えなかったので飛ばしました。

Mediator、全ては相談役がしっている

振る舞い + オブジェクト

このパターンは、関連するクラスの間に仲介クラスを置いてクラスどうしの結合度を弱くする事を可能にするパターンです。
結合度が低くなることでテストを容易にすることも可能になるので上手に使いこなしたいパターンです。

サンプルのチャットパターンがすごく分かりやすかったので、同じ仕様を採用します。

参加するユーザークラス

/*
ユーザークラス
*/
class User
{
	//参加しているチャットループ
	private $chatroom;
	//名前
	private $name;
	
	//コンストラクタ
	public function __construct($name)
	{
		$this->name = $name;
	}
	
	//名前の取得
	public function getName()
	{
		return $this->name;
	}
	
	//チャットルームへの入室
	public function setChatRoom(ChatRoom $chatroom)
	{
		$this->chatroom = $chatroom;
	}
	
	//参加中のチャットループの取得
	public function getChatRoom()
	{
		return $this->chatroom;
	}
	
	//メッセージの送信
	public function setMessage($to, $message)
	{
		$this->chatroom->setMessage($this->name, $to, $message);
	}
	
	//メッセージの受信
	public function receiveMessage($from, $message)
	{
		printf("%sさんからメッセージ : %s\n",$from,$message);
	}
}

Mediator部分のチャットクラス

/*
チャットクラス (Mediator)
*/
class ChatRoom
{
	//参加ユーザー
	private $users = array();
	
	//ログイン
	public function login(User $user)
	{
		$user->setChatRoom($this);
		if( !array_key_exists($user->getName(), $this->users))
		{
			$this->users[$user->getName()] = $user;
			printf("%sさんが入室しました\n",$user->getName());
		}
	}
	
	//メッセージの送信
	public function setMessage($from, $to, $message)
	{
		if( array_key_exists($to, $this->users))
		{
			$this->users[$to]->receiveMessage($from, $message);
		}
		else
		{
			printf("%sさんへのメッセージ送信に失敗しました\n",$to);		}
	}
}

使ってみる

$chatroom = new ChatRoom();

$user1 = new User("U001");
$user2 = new User("U002");
$user3 = new User("U003");
$user4 = new User("U004");
$user5 = new User("U005");

$chatroom->login($user1);
$chatroom->login($user2);
$chatroom->login($user3);

$user1->setMessage('U002',"U002さんこんにちは");
$user2->setMessage('U001',"U001さんこんにちは!");
$user2->setMessage('U003',"U003さんもこんにちは!");
$user3->setMessage('U002',"U002さんこんにちは!");

$user3->setMessage('U004',"U004さんいます?");
$php mediator.php
U001さんが入室しました
U002さんが入室しました
U003さんが入室しました
U001さんからメッセージ : U002さんこんにちは
U002さんからメッセージ : U001さんこんにちは!
U002さんからメッセージ : U003さんもこんにちは!
U003さんからメッセージ : U002さんこんにちは!
U004さんへのメッセージ送信に失敗しました

不参加の人がちゃんと失敗しています。
Userクラスから見た手続きは同じですが、クラス間のやりとりはMediatorのChatクラスが全て担当しているのが分かると思います。