この記事はPHPで学ぶデザインパターン Advent Calendar 2018の記事です。
今回はStrategyパターンについてかきます。
Strategyパターンは、アルゴリズムの切り替えを容易にするようなパターンです。
異なる処理をそれぞれ別のクラスに定義するため、 処理を動的に選択できるだけでなく、条件分岐を減らすことも可能としてします。
OCP(open/closed principle)に忠実なパターンの一つでもあります。
単純な例でStrategyパターンの実装を見てみます。
<?php
class Context
{
private $notification;
public function __construct(NotificationInterface $notification)
{
$this->notification = $notification;
}
public function execute()
{
return $this->notification->notify();
}
}
interface NotificationInterface
{
public function notify();
}
class SlackNotification implements NotificationInterface
{
public function __construct($message)
{
$this->message = $message;
}
public function notify()
{
echo $this->message . '- sent by Slack';
}
}
class EmailNotification implements NotificationInterface
{
public function __construct($message)
{
$this->message = $message;
}
public function notify()
{
echo $this->message . '- sent by Email';
}
}
$message = "Hello World!";
$slack = new SlackNotification($message);
$context = new Context($slack);
$context->execute(); // Hello World - sent by Slack
$email = new EmailNotification($message);
$context = new Context($email);
$context->execute(); // Hello World - sent by Email
Contextクラスの実装をinterfaceを依存させることで"戦略”をクライアント側から切り替えられるようにしています。
これはよく見る実装なのではないでしょうか?
振る舞いが分離されているので、OCPに従った形になっているはず。
拡張に対しては、NotificationInterfaceの実装を追加するだけ、修正に対しては、NotificationInterfaceの実装を修正するだけ、という感じになっているかと思います。
GoFは知らずしらずに利用していることがあるのでちゃんと覚えておいても損はないなーと思いました。
関連書籍