会員ランクごとに画面イメージを切り替えよう パート2
会員のランクによって画面(Web)のイメージを変えたいと思いました。 さっそく書いてみましょう。
interface Template
{
public function show(): void;
}
class BronzRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Bronzeランクヘッダー' . "\n";
}
}
class BronzRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Bronzeランクボディ' . "\n";
}
}
class SilverRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Silverランクヘッダー' . "\n";
}
}
class SilverRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Silverランクボディ' . "\n";
}
}
class CommonFooterTemplate implements Template
{
public function show(): void
{
echo '共通フッター' . "\n";
}
}
class GoldRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Goldランクヘッダー' . "\n";
}
}
class GoldRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Goldランクボディ' . "\n";
}
}
class GoldRankFooterTemplate implements Template
{
public function show(): void
{
echo 'Goldランクフッター' . "\n";
}
}
$header = new GoldRankHeaderTemplate();
$header->show();
$body = new GoldRankBodyTemplate();
$body->show();
$footer = new GoldRankFooterTemplate();
$footer->show();
画面表示用の部品が用意されていて、ランクごとに組み合わせて使えるようになっています。 しかし、次のような不具合が生まれる可能性もあります。
$header = new BronzRankHeaderTemplate();
$header->show();
$body = new SilverRankBodyTemplate();
$body->show();
$footer = new GoldRankFooterTemplate();
$footer->show();
ブロンズ会員用のヘッダーに、シルバー会員用のボディー。 仕様上はありえない組み合わせですね。
Abstract Factoryパターンで防いでみましょう
Abstract Factoryパターンとは
決まった組み合わせのインスタンスを生成するパターンです.
abstract class AbstractFactory
{
public abstract function getHeader(): Template;
public abstract function getBody(): Template;
public abstract function getFooter(): Template;
}
interface Template
{
public function show(): void;
}
class BronzRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Bronzeランクヘッダー' . "\n";
}
}
class BronzRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Bronzeランクボディ' . "\n";
}
}
class SilverRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Silverランクヘッダー' . "\n";
}
}
class SilverRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Silverランクボディ' . "\n";
}
}
class CommonFooterTemplate implements Template
{
public function show(): void
{
echo '共通フッター' . "\n";
}
}
class GoldRankHeaderTemplate implements Template
{
public function show(): void
{
echo 'Goldランクヘッダー' . "\n";
}
}
class GoldRankBodyTemplate implements Template
{
public function show(): void
{
echo 'Goldランクボディ' . "\n";
}
}
class GoldRankFooterTemplate implements Template
{
public function show(): void
{
echo 'Goldランクフッター' . "\n";
}
}
class BronzeRankTemplateFactory extends AbstractFactory
{
public function getHeader(): Template
{
return new BronzRankHeaderTemplate();
}
public function getBody(): Template
{
return new BronzRankBodyTemplate();
}
public function getFooter(): Template
{
return new CommonFooterTemplate();
}
}
class SilverRankTemplateFactory extends AbstractFactory
{
public function getHeader(): Template
{
return new SilverRankHeaderTemplate();
}
public function getBody(): Template
{
return new SilverRankBodyTemplate();
}
public function getFooter(): Template
{
return new CommonFooterTemplate();
}
}
class GoldRankTemplateFactory extends AbstractFactory
{
public function getHeader(): Template
{
return new GoldRankHeaderTemplate();
}
public function getBody(): Template
{
return new GoldRankBodyTemplate();
}
public function getFooter(): Template
{
return new GoldRankFooterTemplate();
}
}
$template = new GoldRankTemplateFactory();
$header = $template->getHeader();
$header->show();
$body = $template->getBody();
$body->show();
$footer = $template->getFooter();
$footer->show();
ランクに従ったTemplate Factoryを選ぶことで、想定外の組み合わせを防ぐことができます。
しかし、インスタンスの呼び出し順を決めることはできないので、呼び出し順も決めたい場合は、 Template Methodパターンと組み合わせることも検討すると良いでしょう。