<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>@blog.justoneplanet.info &#187; デザインパターン</title>
	<atom:link href="http://blog.justoneplanet.info/category/computer-language/php/design-pattern/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.justoneplanet.info</link>
	<description>日々勉強</description>
	<lastBuildDate>Wed, 08 Feb 2012 02:57:17 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHPでStrategyパターン</title>
		<link>http://blog.justoneplanet.info/2010/08/30/php%e3%81%a7strategy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/</link>
		<comments>http://blog.justoneplanet.info/2010/08/30/php%e3%81%a7strategy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 15:09:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4355</guid>
		<description><![CDATA[アルゴリズムをクラスとして定義し、対象によって切り替える。 ■実装 class ItemDataContext { private $_strategy; public function __construct(Read [...]]]></description>
			<content:encoded><![CDATA[<p>アルゴリズムをクラスとして定義し、対象によって切り替える。</p>
<h3>■実装</h3>
<pre class="brush: php;">
class ItemDataContext
{
    private $_strategy;

    public function __construct(ReadItemDataStrategy $strategy){
        $this-&gt;_strategy = $strategy;
    }

    public function getItemData(){
        return $this-&gt;strategy-&gt;getData();
    }
}
</pre>
<pre class="brush: php;">
abstract class ReadItemDataStrategy
{
    private $_filename;
    public function __construct($filename)
    {
        $this-&gt;_filename = $filename;
    }

    public function getData()
    {
        if(!is_readable($filename = $this-&gt;getFilename())){
            throw new Exception('is not readable : ' . $filename);
        }
        return $this-&gt;readData($filename);
    }

    public function getFilename()
    {
        return $this-&gt;_filename;
    }

    protected abstract function readData($filename);
}
</pre>
<section class="kakomi">
<h4>ReadFixedLengthDataStrategy.php</h4>
<pre class="brush: php;">
class ReadFixedLengthDataStrategy extends ReadItemDataStrategy
{
    protected function readData($filename){
        // implementation
    }
}
</pre>
<h4>ReadTabSeparatedDataStrategy.php</h4>
<pre class="brush: php;">
class ReadTabSeparatedDataStrategy extends ReadItemDataStrategy
{
    protected function readData($filename){
        // implementation
    }
}
</pre>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/08/30/php%e3%81%a7strategy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでProxyパターン</title>
		<link>http://blog.justoneplanet.info/2010/08/28/php%e3%81%a7proxy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/</link>
		<comments>http://blog.justoneplanet.info/2010/08/28/php%e3%81%a7proxy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 14:19:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4349</guid>
		<description><![CDATA[■実装 とりあえずパターンの要ではないクラス。 class Item { private $_id; private $_name; public function __construct($id, $name) { $ [...]]]></description>
			<content:encoded><![CDATA[<h3>■実装</h3>
<p>とりあえずパターンの要ではないクラス。</p>
<pre class="brush: php;">
class Item
{
    private $_id;
    private $_name;
    public function __construct($id, $name)
    {
        $this-&gt;_id   = $id;
        $this-&gt;_name = $name;
    }

    public function getId()
    {
        return $this-&gt;_id;
    }

    public function getName()
    {
        return $this-&gt;_name;
    }
}
</pre>
<h4>ItemDao.php</h4>
<pre class="brush: php;">
interface ItemDao
{
    public function findById($id);
}
</pre>
<section class="kakomi">
<h5>DbItemDao.php</h5>
<p>DBからアイテムデータを取得して生成したインスタンスを返す本番用クラス。</p>
<pre class="brush: php;">
class DbItemDao implements ItemDao
{
    public function findById($id)
    {
        $fh = fopen('data.txt', 'r');
        $item = null;
        while($buffer = fgets($fh, 4096)){
            $id1  = trim(substr($buffer, 0, 10));
            $name = trim(substr($buffer, 10));
            if($id === (int) $id1){
                $item = new Item($id1, $name);
                break;
            }
        }
        fclose($fh);
        return $item;
    }
}
</pre>
<h5>MockItemDao.php</h5>
<p>ダミーデータで作ったインスタンスを返すテスト用クラス。</p>
<pre class="brush: php;">
class MockItemDao implements ItemDao
{
    public function findById($id)
    {
        $item = new Item($id, 'dummy');
        return $item;
    }
}
</pre>
</section>
<h4>ItemDaoProxy.php</h4>
<pre class="brush: php;">
class ItemDaoProxy
{
    private $_dao;
    private $_cache;
    public function __construct(ItemDao $dao)
    {
        $this-&gt;_dao   = $dao;
        $this-&gt;_cache = array();
    }

    public function findById($id)
    {
        if(array_key_exists($id, $this-&gt;_cache)){
            return $this-&gt;_cache[$id];
        }
        $this-&gt;_cache[$id] = $this-&gt;dao-&gt;findById($id);
        return $this-&gt;_cache[$id];
    }
}
</pre>
<p>■クライアントコード</p>
<p>以下のようにすることで使うことができる。</p>
<pre class="brush: php;">
switch($mode){
    case 'test':
        $dao = new MockItemDao();
        break;
    case 'production':
        $dao = new DbItemDao();
        break;
}
$proxy = new ItemDaoProxy($dao);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/08/28/php%e3%81%a7proxy%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでObserverパターン</title>
		<link>http://blog.justoneplanet.info/2010/08/27/php%e3%81%a7observer%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/</link>
		<comments>http://blog.justoneplanet.info/2010/08/27/php%e3%81%a7observer%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 13:54:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4347</guid>
		<description><![CDATA[class Cart { private $_items private $_listeners; public function __construct() { $this-&#62;_items = array();  [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: php;">
class Cart
{
    private $_items
    private $_listeners;

    public function __construct()
    {
        $this-&gt;_items     = array();
        $this-&gt;_listeners = array();
    }

    public function add($cd)
    {
        $this-&gt;_items[$cd] = (isset($this-&gt;_items[$cd]))? ++$this-&gt;_items[$cd] : 1;
        $this-&gt;notify();
    }

    public function remove($cd)
    {
        $this-&gt;_items[$cd] = (isset($this-&gt;_items[$cd]))? --$this-&gt;_items[$cd] : 0;
        if($this-&gt;_items[$cd] &lt;= 0){
            unset($this-&gt;_items[$cd]);
        }
        $this-&gt;notify();
    }

    public function get()
    {
        return $this-&gt;_items;
    }

    public function has($cd)
    {
        return array_key_exists($cd, $this-&gt;_items);
    }

    public function notify()
    {
        foreach($this-&gt;_listeners as $listener){
            $listener-&gt;update($this);
        }
    }

    public function addListener(CartListener $listener)
    {
        $this-&gt;_listeners[get_class($listener)] = $listener;
    }
}
</pre>
<h4>Listener.php</h4>
<p>以下のようにインターフェースを定義する。</p>
<pre class="brush: php;">
interface Listener
{
    public function update(Cart $cart);
}
</pre>
<section class="kakomi">
<p>以下のようにListenerを実装する。</p>
<h5>PresentListener</h5>
<pre class="brush: php;">
class PresentListener implements Listener
{
    const PRESENT_TARGET = '30:cookie';
    const PRESENT_ITEM   = '99:present';

    public function __construct()
    {
    }

    public function update(Cart $cart)
    {
        if($cart-&gt;hasItem(self::PRESENT_TARGET) &amp;&amp; !$cart-&gt;hasItem(self::PRESENT_ITEM)){
            $cart-&gt;add(self::PRESENT_ITEM);
        }
        if(!$cart-&gt;hasItem(self::PRESENT_TARGET) &amp;&amp; $cart-&gt;hasItem(self::PRESENT_ITEM)){
            $cart-&gt;remove(self::PRESENT_ITEM);
        }
    }
}
</pre>
<h5>LoginListener</h5>
<pre class="brush: php;">
class LoginListener implements Listener
{
    public function __construct()
    {
    }

    public function update(Cart $cart)
    {
        var_dump($cart-&gt;get());
    }
}
</pre>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/08/27/php%e3%81%a7observer%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facade Pattern</title>
		<link>http://blog.justoneplanet.info/2010/01/02/facade-pattern/</link>
		<comments>http://blog.justoneplanet.info/2010/01/02/facade-pattern/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:16:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=2273</guid>
		<description><![CDATA[■定義 サブシステム内に存在する複数のインターフェースに1つの統一インターフェースを与える。facadeパターンはサブシステムの利用を容易にするための高レベルインターフェースを定義する。窓口的な感じ。 ■コード クライア [...]]]></description>
			<content:encoded><![CDATA[<h3>■定義</h3>
<p>サブシステム内に存在する複数のインターフェースに1つの統一インターフェースを与える。facadeパターンはサブシステムの利用を容易にするための高レベルインターフェースを定義する。窓口的な感じ。</p>
<h3>■コード</h3>
<section class="kakomi">
<h4>クライアントコード</h4>
<pre class="brush: php;">
$order = new Order();

$itemDao = ItemDao::getInstance(); //itemデータアクセスオブジェクト
$order-&gt;addItem(new OrderItem($itemDao-&gt;findById(1), 2));
$order-&gt;addItem(new OrderItem($itemDao-&gt;findById(2), 1));
$order-&gt;addItem(new OrderItem($itemDao-&gt;findById(3), 3));

OrderManager::order($order);// 注文処理
</pre>
</section>
<h4>Order.php</h4>
<pre class="brush: php;">
class Order {
    private $items;
    public function __construct() {
        $this-&gt;items = array();
    }
    public function addItem(OrderItem $orderItem) {
        $this-&gt;items[$orderItem-&gt;getItem()-&gt;getId()] = $orderItem;
    }
    public function getItem() {
        return $this-&gt;items;
    }
}
</pre>
<h4>OrderItem.php</h4>
<pre class="brush: php;">
class OrderItem {
    private $item;
    private $amount;
    public function __construct(Item $item, $amount) {
        $this-&gt;item   = item;
        $this-&gt;amount = amount;
    }
    public function getItem() {
        return $this-&gt;item;
    }
    public function getAmount() {
        return $this-&gt;amount;
    }
}
</pre>
<h4>Item.php</h4>
<pre class="brush: php;">
class Item {
    private $id;
    private $name;
    private $price;
    public function __construct($id, $name, $price) {
        $this-&gt;id    = $id;
        $this-&gt;name  = $name;
        $this-&gt;price = $price;
    }
    public function getId() {
        return $this-&gt;id;
    }
    public function getName() {
        return $this-&gt;name;
    }
    public function getPrice() {
        return $this-&gt;price;
    }
}
</pre>
<h4>OrderManager.php</h4>
<pre class="brush: php;">
class OrderManager {
    public static function order(Order $order) {
        $itemDao = ItemDao::getInstance();
        foreach($order-&gt;getItems() as $orderItem) {
            $itemDao-&gt;setAsign($orderItem);
        }
        OrderDao::createOrder($order);
    }
}
</pre>
<section class="kakomi">
<h4>ItemDao.php</h4>
<pre class="brush: php;">
/**
 * シングルトン
 */
class ItemDao {
    private static $instance;
    private $items;
    private function __construct() {
        // 以下の構造を生成する
        // $this-&gt;items[アイテムのID] = アイテム
    }
    public static function getInstance() {
        if(!isset(self::instance)) {
            self::instance = new ItemDao();
        }
        return self::instance;
    }
    public function findById($itemId) {
        if(array_key_exists($itemId, $this-&gt;items)) {
            return $this-&gt;items[$itemId]
        }
        else {
            return null;
        }
    }
    public function setAside(OrderItem $orderItem) {
        return $orderItem-&gt;getItem()-&gt;getName;
    }
}
</pre>
<h4>OrderDao.php</h4>
<pre class="brush: php;">
class OrderDao {
    public static function createOrder(Order $order) {
        // orderをループしてゴニョゴニョ
    }
}
</pre>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/01/02/facade-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでデザインパターン:FactoryMethod（ファクトリーメソッド）</title>
		<link>http://blog.justoneplanet.info/2010/01/02/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3factorymethod%ef%bc%88%e3%83%95%e3%82%a1%e3%82%af%e3%83%88%e3%83%aa%e3%83%bc%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/</link>
		<comments>http://blog.justoneplanet.info/2010/01/02/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3factorymethod%ef%bc%88%e3%83%95%e3%82%a1%e3%82%af%e3%83%88%e3%83%aa%e3%83%bc%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:30:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=2265</guid>
		<description><![CDATA[メリットは「生成と処理を分離し利用側の変更なしに処理（クラス）を追加したりできる」ことである。 ■コード 今回使用するのは以下のxmlとcsvファイルの2種類とする。 xml &#60;data&#62; &#60;perso [...]]]></description>
			<content:encoded><![CDATA[<p>メリットは「生成と処理を分離し利用側の変更なしに処理（クラス）を追加したりできる」ことである。</p>
<h3>■コード</h3>
<p>今回使用するのは以下のxmlとcsvファイルの2種類とする。</p>
<div class="kakomi">
<h4>xml</h4>
<pre class="brush: xml;">
&lt;data&gt;
    &lt;person&gt;
        &lt;name&gt;John&lt;/name&gt;
        &lt;occupation&gt;racer&lt;/occupation&gt;
    &lt;/person&gt;
    &lt;person&gt;
        &lt;name&gt;Mike&lt;/name&gt;
        &lt;occupation&gt;banker&lt;/occupation&gt;
    &lt;/person&gt;
    &lt;person&gt;
        &lt;name&gt;Nick&lt;/name&gt;
        &lt;occupation&gt;runner&lt;/occupation&gt;
    &lt;/person&gt;
&lt;/data&gt;
</pre>
<h4>csv</h4>
<p>John,racer<br />
Mike,banker<br />
Nick,runner</p>
</div>
<p>template methodで処理の枠だけ定義する。</p>
<pre class="brush: php;">
interface Printer
{
    public function read();
    public function output();
}
</pre>
<p>以下のCsvFilePrinterクラスとXmlFilePrinterクラスで具体的な処理を記述する。</p>
<pre class="brush: php;">
class CsvFilePrinter implements Printer
{
    private $_filename;
    private $_fh;
    public function __construct($filename)
    {
        $this-&gt;_filename = $filename;
    }
    public function read()
    {
        $this-&gt;_fh = fopen($this-&gt;_filename, 'r');
    }
    public function output()
    {
        print(&quot;&lt;table&gt;&quot;);
        while($data = fgetcsv($this-&gt;_fh)){
            print(&quot;&lt;tr&gt;&quot;);
            for($i = 0, $n = count($data); $i &lt; $n; $i++){
                print(&quot;&lt;td&gt;{$data[$i]}&lt;/td&gt;&quot;);
            }
            print(&quot;&lt;/tr&gt;&quot;);
        }
        print(&quot;&lt;/table&gt;&quot;);
        fclose($this-&gt;_fh);
    }
}
class XmlFilePrinter implements Printer
{
    private $_filename;
    private $_rh;
    public function __construct($filename)
    {
        $this-&gt;_filename = $filename;
    }
    public function read()
    {
        $this-&gt;_rh = simplexml_load_file($this-&gt;_filename);
    }
    public function output()
    {
        print('&lt;table&gt;');
        foreach($this-&gt;_rh-&gt;person as $person){
            print('&lt;tr&gt;');
            print(&quot;&lt;td&gt;{$person-&gt;name}&lt;/td&gt;&quot;);
            print(&quot;&lt;td&gt;{$person-&gt;occupation}&lt;/td&gt;&quot;);
            print('&lt;/tr&gt;');
        }
        print('&lt;/table&gt;');
    }
}
</pre>
<h4>Factory部分</h4>
<p>分岐してインスタンスを返すようになっている。</p>
<pre class="brush: php;">
class PrinterFactory
{
    public function getPrinter($filename)
    {
        if(preg_match('/\.csv$/i', $filename)){
            return new CsvFilePrinter($filename);
        }
        elseif(preg_match('/\.xml$/i', $filename)){
            return new XmlFilePrinter($filename);
        }
    }
}
</pre>
<h4>クライアントコード</h4>
<p>以下のように中身を意識することなく使用できる。</p>
<pre class="brush: php;">
$printer = new PrinterFactory();
$data = $printer-&gt;getPrinter('./dat.xml');
$data-&gt;read();
$data-&gt;output();
/*
John	racer
Mike	banker
Nick	runner
*/
$data = $printer-&gt;getPrinter('./dat.csv');
$data-&gt;read();
$data-&gt;output();
/*
John	racer
Mike	banker
Nick	runner
*/
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/01/02/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3factorymethod%ef%bc%88%e3%83%95%e3%82%a1%e3%82%af%e3%83%88%e3%83%aa%e3%83%bc%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでデザインパターン:TemplateMethod（テンプレートメソッド）</title>
		<link>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3templatemethod%ef%bc%88%e3%83%86%e3%83%b3%e3%83%97%e3%83%ac%e3%83%bc%e3%83%88%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/</link>
		<comments>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3templatemethod%ef%bc%88%e3%83%86%e3%83%b3%e3%83%97%e3%83%ac%e3%83%bc%e3%83%88%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 11:34:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=2261</guid>
		<description><![CDATA[メリットは「共通処理をまとめ具体的な処理をサブクラスに実装させられる」こと。 ■コード 以下のように共通処理を定義する。具体的な処理が必要な部分は抽象メソッドにしておき、それらをdisplayからコールするようにする。  [...]]]></description>
			<content:encoded><![CDATA[<p>メリットは「共通処理をまとめ具体的な処理をサブクラスに実装させられる」こと。</p>
<h3>■コード</h3>
<p>以下のように共通処理を定義する。具体的な処理が必要な部分は抽象メソッドにしておき、それらをdisplayからコールするようにする。</p>
<pre class="brush: php;">
abstract class Display
{
    private $_data;
    public function __construct($data)
    {
        $this-&gt;_data = $data;
    }
    public function getData()
    {
        return $this-&gt;_data;
    }
    public function display()
    {
        $this-&gt;header();
        $this-&gt;body();
        $this-&gt;footer();
    }
    abstract protected function header();
    abstract protected function body();
    abstract protected function footer();
}
</pre>
<p>以下のようにDisplayクラスを継承したクラス（DisplayAsPlain、DisplayAsList）を定義し、それぞれに具体的（⇔抽象）な処理を記述する。</p>
<pre class="brush: php;">
class DisplayAsPlain extends Display
{
    protected function header(){}
    protected function body()
    {
        foreach($this-&gt;getData() as $key =&gt; $value){
            print(&quot;{$key} {$value}\n&quot;);
        }
    }
    protected function footer(){}
}

class DisplayAsList extends Display
{
    protected function header()
    {
        print(&quot;&lt;ul&gt;\n&quot;);
    }
    protected function body()
    {
        foreach($this-&gt;getData() as $key =&gt; $value){
            print(&quot;&lt;li&gt;{$key}: {$value}&lt;/li&gt;\n&quot;);
        }
    }
    protected function footer()
    {
        print('&lt;/ul&gt;');
    }
}
</pre>
<p>新しい表示形式を加えたい場合は、Displayを継承したクラスを作ってあげればよい。</p>
<h4>クライアントコード</h4>
<pre class="brush: php;">
$data = array(
    'John' =&gt; 'banker',
    'Mike' =&gt; 'driver',
    'Nick' =&gt; 'scientist'
);
$plain = new DisplayAsPlain($data);
$plain-&gt;display();
/*
John banker
Mike driver
Nick scientist
*/
$list = new DisplayAsList($data);
$list-&gt;display();
/*
&lt;ul&gt;
&lt;li&gt;John: banker&lt;/li&gt;
&lt;li&gt;Mike: driver&lt;/li&gt;
&lt;li&gt;Nick: scientist&lt;/li&gt;
&lt;/ul&gt;
*/
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3templatemethod%ef%bc%88%e3%83%86%e3%83%b3%e3%83%97%e3%83%ac%e3%83%bc%e3%83%88%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPでデザインパターン:Adapter（アダプタ）</title>
		<link>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3adapter%ef%bc%88%e3%82%a2%e3%83%80%e3%83%97%e3%82%bf%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3adapter%ef%bc%88%e3%82%a2%e3%83%80%e3%83%97%e3%82%bf%ef%bc%89/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 10:30:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=2254</guid>
		<description><![CDATA[メリットは「既存のコードを再利用出来ること」である。 ■コード 以下の様なクラスがあるとする。 class SoccerPlayer { private $_name; public function __constru [...]]]></description>
			<content:encoded><![CDATA[<p>メリットは「既存のコードを再利用出来ること」である。</p>
<h3>■コード</h3>
<p>以下の様なクラスがあるとする。</p>
<pre class="brush: php;">
class SoccerPlayer
{
    private $_name;
    public function __construct($name)
    {
        $this-&gt;_name = $name;
    }
    public function introduce()
    {
        print($this-&gt;_name);
    }
}
</pre>
<p>以下の様なインターフェイスがあり、メソッドを「getName」で統一したい。</p>
<pre class="brush: php;">
interface Person
{
    public function getName();
}
</pre>
<p>更に、使用実績があるSoccerPlayerクラスのコードを変更することなく、「getName」でSoccerPlayerクラスのメソッド「introduce」をcallしたい。そんな要望に応えるのがAdapterパターンだ。</p>
<div class="kakomi">
<h4>継承の場合</h4>
<p>継承の場合はコンストラクタの引数は「$name」であり、内部に保持するのも「$name」である。</p>
<pre class="brush: php;">
class SoccerPerson extends SoccerPlayer implements Person
{
    public function __construct($name)
    {
        parent::__construct($name);
    }
    public function getName()
    {
        parent::introduce();
    }
}
</pre>
<h5>クライアント側</h5>
<p>継承を使用しているので、当然ながら元のメソッド「introduce」も使えてしまう。</p>
<pre class="brush: php;">
$john = new SoccerPerson('John');
$john-&gt;getName();//John
$john-&gt;introduce();//John
</pre>
</div>
<div class="kakomi">
<h4>委譲の場合</h4>
<p>継承の場合はコンストラクタの引数は「$name」であり、内部に保持するのは「SoccerPlayerのインスタンス」である。従ってgetNameした時、そのインスタンス経由でintroduceがコールできる。</p>
<pre class="brush: php;">
class SoccerPerson implements Person
{
    private $_person;
    public function __construct($name)
    {
        $this-&gt;_person = new SoccerPlayer($name);
    }
    public function getName()
    {
        $this-&gt;_person-&gt;introduce();
    }
}
</pre>
<h5>クライアント側</h5>
<p>委譲（継承ではない）を使用しているので、メソッド「introduce」は使えない。</p>
<pre class="brush: php;">
$john = new SoccerPerson('John');
$john-&gt;getName();//John
$john-&gt;introduce();//Fatal error
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/01/01/php%e3%81%a7%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3adapter%ef%bc%88%e3%82%a2%e3%83%80%e3%83%97%e3%82%bf%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decorator</title>
		<link>http://blog.justoneplanet.info/2010/01/01/%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3decorator%ef%bc%88%e8%a3%85%e9%a3%be%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2010/01/01/%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3decorator%ef%bc%88%e8%a3%85%e9%a3%be%ef%bc%89/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 08:04:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=2245</guid>
		<description><![CDATA[■コード Text.php interface Text { public function getText(); public function setText($str); } PlainText.php class [...]]]></description>
			<content:encoded><![CDATA[<h3>■コード</h3>
<section class="kakomi">
<h4>Text.php</h4>
<pre class="brush: php;">
interface Text {
    public function getText();
    public function setText($str);
}
</pre>
</section>
<h4>PlainText.php</h4>
<pre class="brush: php;">
class PlainText implements Text
{
    private $_textString = null;
    public function getText()
    {
        return $this-&gt;_textString;
    }
    public function setText($str)
    {
        $this-&gt;_textString = $str;
    }
}
</pre>
<section class="kakomi">
<h4>TextDecorator.php</h4>
<p>内部にテキストオブジェクトを保持し同様のインターフェースを提供する。</p>
<pre class="brush: php;">
abstract class TextDecorator implements Text
{
    private $_text;
    public function __construct(Text $target) {
	    $this-&gt;_text = $target;
    }
    public function getText() {
        return $this-&gt;_text-&gt;getText();
    }
    public function setText($str) {
        $this-&gt;_text-&gt;setText($str);
    }
}
</pre>
</section>
<h4>UpperCaseText.php</h4>
<pre class="brush: php;">
class UpperCaseText extends TextDecorator {
    public function __construct(Text $target) {
        parent::__construct($target);
    }
    public function getText() {
        $str = parent::getText();
        $str = strtoupper($str);
        return $str;
    }
}
</pre>
<h4>DoubleByteText.php</h4>
<pre class="brush: php;">
class DoubleByteText extends TextDecorator {
    public function __construct(Text $target) {
        parent::__construct($target);
    }
    public function getText() {
        $str = parent::getText();
        $str = mb_convert_kana($str, 'RANSKV');
        return $str;
    }
}
</pre>
<pre class="brush: php;">
$text = new PlainText();
$text-&gt;setText('This is a pen.');
$dbText = new DoubleByteText($text);
var_dump($dbText-&gt;getText());//string(42) &quot;Ｔｈｉｓ　ｉｓ　ａ　ｐｅｎ．&quot;
$ucText = new UpperCaseText($text);
var_dump($ucText-&gt;getText());//string(14) &quot;THIS IS A PEN.&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2010/01/01/%e3%83%87%e3%82%b6%e3%82%a4%e3%83%b3%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3decorator%ef%bc%88%e8%a3%85%e9%a3%be%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compositeパターン</title>
		<link>http://blog.justoneplanet.info/2009/12/12/composite%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/</link>
		<comments>http://blog.justoneplanet.info/2009/12/12/composite%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 15:26:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3383</guid>
		<description><![CDATA[Composite（コンポジット・パターン）を使うと木構造のような再帰的なパターンを表現することができる。 ■コード Component.php abstract class Component { abstract p [...]]]></description>
			<content:encoded><![CDATA[<p>Composite（コンポジット・パターン）を使うと木構造のような再帰的なパターンを表現することができる。</p>
<h3>■コード</h3>
<section class="kakomi">
<h4>Component.php</h4>
<pre class="brush: php;">
abstract class Component
{
    abstract public function add(Component $branch);
}
</pre>
</section>
<h4>Branch.php</h4>
<p>枝のクラス。</p>
<pre class="brush: php;">
class Branch extends Component
{
    private $_children;
    public function __construct()
    {
        $this-&gt;_children = array();
    }
    public function add(Component $branch)
    {
        return array_push($this-&gt;_children, $branch);
    }
}
</pre>
<h4>Leaf.php</h4>
<p>葉っぱ。</p>
<pre class="brush: php;">
class Leaf extends Component
{
    public function add(Component $branch)
    {
        throw new Exception('leaves cannot have any leaves');
    }
}
</pre>
<h3>■クライアントコード</h3>
<pre class="brush: php;">
$branch = new Branch();
$branch-&gt;add(new Leaf());
$branch-&gt;add(new Leaf());
$branch-&gt;add(new Leaf());

var_dump($branch);
/*
object(Branch)[1]
  private '_children' =&gt;
    array
      0 =&gt;
        object(Leaf)[2]
      1 =&gt;
        object(Leaf)[3]
      2 =&gt;
        object(Leaf)[4]
 */
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/12/12/composite%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interpreter Pattern</title>
		<link>http://blog.justoneplanet.info/2009/12/11/interpreter-pattern/</link>
		<comments>http://blog.justoneplanet.info/2009/12/11/interpreter-pattern/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 18:34:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4842</guid>
		<description><![CDATA[言語の文法 &#60;Job&#62; ::= begin &#60;CommandList&#62; &#60;CommandList&#62; ::= &#60;Command&#62;* end &#60;Command&#62; : [...]]]></description>
			<content:encoded><![CDATA[<section class="kakomi">
<h4>言語の文法</h4>
<pre class="brush: xml;">
&lt;Job&gt; ::= begin &lt;CommandList&gt;
&lt;CommandList&gt; ::= &lt;Command&gt;* end
&lt;Command&gt; ::= diskspace | date | line
</pre>
</section>
<pre class="brush: php;">
interface Command {
    public function execute(Context $context);
}
</pre>
<section class="kakomi">
<h4>JobCommand.php</h4>
<pre class="brush: xml;">
&lt;Job&gt; ::= begin &lt;CommandList&gt;
</pre>
<pre class="brush: php;">
class JobCommand implements Command {
    public function execute(Context $context) {
        if($context-&gt;getCurrentCommand() !== 'begin') {
            throw new RuntimeException();
        }
        $commandList = new CommandListCommand();
        $commandList-&gt;execute($context-&gt;next);
    }
}
</pre>
<h4>CommandListCommand.php</h4>
<pre class="brush: xml;">
&lt;CommandList&gt; ::= &lt;Command&gt;* end
</pre>
<pre class="brush: php;">
class CommandListCommand implements Command {
    public function execute(Context $context) {
        while(true) {
            $currentCommand = $context-&gt;getCurrentCommand();
            if(is_null($currentCommand)) {
                throw new RuntimeException();
            }
            else if($currentCommand === 'end') {
                break;
            }
            else {
                $command = new CommandCommand();
                $command-&gt;execute($context);
            }
        }
        $context-&gt;next();
    }
}
</pre>
<h4>CommandCommand.php</h4>
<pre class="brush: xml;">
&lt;Command&gt; ::= diskspace | date | line
</pre>
<pre class="brush: php;">
class CommandCommand implements Command {
    public function execute(Context $context) {
        $currentCommand = $context-&gt;getCurrentCommand();
        if($currentCommand === 'diskspace') {
            // 空き容量を計算して出力
        }
        else if($currentCommand === 'date') {
            // 日付出力
        }
        else if($currentCommand === 'line') {
            // 罫線を出力
        }
        else {
            new RuntimeException();
        }
    }
}
</pre>
</section>
<h4>Context.php</h4>
<pre class="brush: php;">
class Context {
    private $commands;
    private $currentIndex = 0;
    private $maxIndex = 0;
    public function __construct($command) {
        $this-&gt;commands = split(' +', trim($command));
        $this-&gt;maxIndex = count($this-&gt;commands);
    }
    public function next() {
        $this-&gt;currentIndex++;
        return $this;
    }
    public function getCurrentCommand() {
        if(!array_key_exists($this-&gt;currentIndex, $this-&gt;commands)) {
            return null;
        }
        return trim($this-&gt;commands[$this-&gt;currentIndex]);
    }
}
</pre>
<p></3>■クライアントコード</h3>
<pre class="brush: php;">
$job = new JobCommand();
$job-&gt;execute(new Context('begin date line diskspace end'));
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/12/11/interpreter-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flyweight Pattern</title>
		<link>http://blog.justoneplanet.info/2009/12/11/flyweight-pattern/</link>
		<comments>http://blog.justoneplanet.info/2009/12/11/flyweight-pattern/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 18:10:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4840</guid>
		<description><![CDATA[同じものは一度しか作らない。 ■コード Item.php class Item { private $code; private $name; private $price; public function __cons [...]]]></description>
			<content:encoded><![CDATA[<p>同じものは一度しか作らない。</p>
<h3>■コード</h3>
<h4>Item.php</h4>
<pre class="brush: php;">
class Item {
    private $code;
    private $name;
    private $price;
    public function __construct($code, $name, $price) {
        $this-&gt;code = $code;
        $this-&gt;name = $name;
        $this-&gt;price = $price;
    }
}
</pre>
<h4>ItemFactory.php</h4>
<pre class="brush: php;">
class ItemFactory {
    private $pool;
    private static $instance = null;
    private function __construct($filename) {
        $this-&gt;buildPool($filename);
    }
    public static function getInstance($filename) {
        if(!is_null(self::$instance)) {
            self::$instance = new ItemFactory($filename);
        }
        return self::$instance;
    }
    public function getItem($code) {
        if(array_key_exists($code, $this-&gt;pool)) {
            return $this-&gt;pool($code);
        }
        else {
            return null;
        }
    }
    public function buildPool($filename) {
        $this-&gt;pool = array();
        $fh = fopen($filename, 'r');
        while($buffer = fgets($fp, 4096)) {
            list($itemCode, $itemName, $price) = split(&quot;\t&quot;, $buffer);
            $this-&gt;pool[$itemCode] = new Item($itemCode, $itemName, $price);
        }
        fclose($fh);
    }
    public final __clone() {
        throw new RuntimeException();
    }
}
</pre>
<h3>■クライアントコード</h3>
<pre class="brush: php;">
$factory = ItemFactory::getInstance('list.dat');
$factory-&gt;getItem(123);// 何度コールしても同じインスタンスが返るはず
$factory-&gt;getItem(456);//
$factory-&gt;getItem(789);//
</pre>
<p>Singletonをまとめた感じだ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/12/11/flyweight-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Command Pattern</title>
		<link>http://blog.justoneplanet.info/2009/12/09/command-pattern/</link>
		<comments>http://blog.justoneplanet.info/2009/12/09/command-pattern/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 15:05:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[デザインパターン]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4831</guid>
		<description><![CDATA[■コード File.php class File { private $name; public function __construct($name) { $this-&#62;name = $name; } publi [...]]]></description>
			<content:encoded><![CDATA[<h3>■コード</h3>
<h4>File.php</h4>
<pre class="brush: php;">
class File {
    private $name;
    public function __construct($name) {
        $this-&gt;name = $name;
    }
    public function decompress() {
        //
    }
    public function compress() {
        //
    }
    public function create() {
        //
    }
}
</pre>
<h4>Command.php</h4>
<pre class="brush: php;">
interface Command {
    public function execute();
}
</pre>
<section class="kakomi">
<h4>TouchCommand.php</h4>
<pre class="brush: php;">
class TouchCommand implements Command {
    private $file;
    public function __construct(File $file) {
        $this-&gt;file = $file;
    }
    public function execute() {
        $this-&gt;file-&gt;create();
    }
}
</pre>
<h4>CompressCommand.php</h4>
<pre class="brush: php;">
class CompressCommand implements Command {
    private $file;
    public function __construct(File $file) {
        $this-&gt;file = $file;
    }
    public function execute() {
        $this-&gt;file-&gt;compress();
    }
}
</pre>
<h4>CopyCommand.php</h4>
<pre class="brush: php;">
class CopyCommand implements Command {
    private $file;
    public function __construct(File $file) {
        $this-&gt;file = $file;
    }
    public function execute() {
        $file = new File('copy_' . $this-&gt;file-&gt;getName());
        $file-&gt;create();
    }
}
</pre>
</section>
<h4>Queue.php</h4>
<pre class="brush: php;">
class Queue {
    private $commands;
    private $currentIndex;
    public function __construct() {
        $this-&gt;commands = array();
        $this-&gt;currenrIndex = 0;
    }
    public function addCommand(Command $command) {
        $this-&gt;commands[] = $command;
    }
    public function run() {
        while(!is_null($command = $this-&gt;next())) {
            $command-&gt;execute();
        }
    }
    private function execute() {
        if(count($this-&gt;commands) === 0 || count($this-&gt;commands) &lt;= $this-&gt;currentIndex) {
            return null;
        }
        else {
            return $this-&gt;commands[$this-&gt;currentIndex++];
        }
    }
}
</pre>
<h3>■クライアントコード</h3>
<pre class="brush: php;">
$queue = new Queue();
$file = new File('hoge.txt');
$queue-&gt;addCommand(new TouchCommand($file));
$queue-&gt;addCommand(new CompressCommand($file));
$queue-&gt;addCommand(new CopyCommand($file));
$queue-&gt;run();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/12/09/command-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

