PHP設計模式—工廠模式之工廠方法模式

定義:

工廠方法模式:定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。

代碼實例:

這裏還是接着上篇簡單工廠模式的那個例子,改成工廠方法模式。

1、創建一個抽象類 ApptEncoder

/**
 * 抽象類
 * Class ApptEncoder
 */
abstract class ApptEncoder
{
    abstract public function encode();
}

2、創建 BloggsCal 格式處理類

/**
 * BloggsCal 格式處理類
 * Class BloggsApptEncoder
 */
class BloggsApptEncoder extends ApptEncoder
{
    public function encode()
    {
        // TODO: Implement encode() method.
        return "Appointment data encoded in BloggsCal format\n";
    }
}

3、創建 MegaCal 格式處理類

/**
 * MegaCal 格式處理類
 * Class MegaApptEncoder
 */
class MegaApptEncoder extends ApptEncoder
{
    public function encode()
    {
        // TODO: Implement encode() method.
        return "Appointment data encoded in MegaCal format\n";
    }
}

4、創建工廠抽象類 CommsManager

/**
 * 工廠抽象類
 * Class CommsManager
 */
abstract class CommsManager
{
    abstract public function getHeaderText();
    abstract public function getApptEncoder();
    abstract public function getFooterText();
}

5、創建 BloggsCal 工廠類

/**
 * BloggsCal 工廠類
 * Class BloggsCommsManager
 */
class BloggsCommsManager extends CommsManager
{
    public function getHeaderText()
    {
        // TODO: Implement getHeaderText() method.
        return "BloggsCal header\n";
    }

    public function getApptEncoder()
    {
        // TODO: Implement getApptEncoder() method.
        return new BloggsApptEncoder();
    }

    public function getFooterText()
    {
        // TODO: Implement getFooterText() method.
        return "BloggsCal footer\n";
    }
}

6、創建 MegaCal 工廠類

/**
 * MegaCal 工廠類
 * Class MegaCommsManager
 */
class MegaCommsManager extends CommsManager
{
    public function getHeaderText()
    {
        // TODO: Implement getHeaderText() method.
        return "MegaCal header\n";
    }

    public function getApptEncoder()
    {
        // TODO: Implement getApptEncoder() method.
        return new MegaApptEncoder();
    }

    public function getFooterText()
    {
        // TODO: Implement getFooterText() method.
        return "MegaCal footer\n";
    }
}

7、調用:

// 如果要換成 MegaCal 格式處理,直接換成 $mar = new MegaCommsManager() 就可以了
$mgr = new BloggsCommsManager();
print $mgr->getHeaderText();
print $mgr->getApptEncoder()->encode();
print $mgr->getFooterText();

8、結果:

BloggsCal header
Appointment data encoded in BloggsCal format
BloggsCal footer

總結:

1、使用工廠方法模式,如果需要新增一種格式處理,就不需要修改原有的工廠類了,只需要爲這些抽象類實現新的子類即可。這樣整個工廠和產品體系其實都沒有修改的變化,而只是擴展的變化,這就符合了“開放-封閉原則”。
2、工廠方法模式實現時,客戶端需要決定實例化哪一個工廠來實現,選擇判斷的問題還是存在的,也就是說,工廠方法把簡單工廠的內部邏輯判斷移到了客戶端代碼來進行。你想要加功能,本來修改工廠類,而現在是修改客戶端。
3、工廠方法模式的缺點是由於每加一個產品,就需要加一個產品工廠的類,增加了額外的開發量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章