【面向對象的PHP】之模式:抽象工廠方法

抽象工廠方法模式

在工廠方法模式中,咱們經過中間件的方式,造成了如下格式的分離:segmentfault

使用者
  ↓
建立者
  ↓
具體產品設計模式

問題

這樣,咱們不管怎樣修正具體產品,都不會影響使用者。如今,咱們能夠作出來一羣小工廠,他們有各自的產品,但造成了模式層面的重複,那麼咱們如何化解這種重複呢?優化

在本篇,將經過抽象工廠方法模式——抽象 - 工廠方法 - 模式,來完成對小公司的整合,最初設計(母公司 - 子公司):編碼

抽象 建立者-產品 的UML

接下來,咱們要經過抽象類解決多個業務並行的問題。spa

如今,咱們要寫一個PIM的數據格式解碼器 - Personal Information Manage,會產生預定(Appt)、待辦事宜(Ttd)、聯繫人(Contact)三種數據格式。設計

咱們就能夠設計出下列UML:code

具體 抽象工廠方法模型的UML

經過CommsManager抽象類,咱們能夠生成具體的全部子公司(子類)。orm

但事實上,這也必定程度的顯示了爲何有些公司作很差某些行業,一旦他哪怕是間接介入子公司,也會影響子公司的血統(這個想法我最先接觸於吳軍先生的《浪潮之巔》)。面向對象設計模式

實現

abstract class CommsManager {
    abstract function getHeaderText();
    abstract function getApptEncoder();
    abstract function getTtdEncoder();
    abstract function getConteactEncoder();
    abstract function getFootText();
}

class BloggsCommsManager extends CommsManager {
    function getHeaderText()
    {
        return "BloggsCal header\n";
    }

    function getApptEncoder()
    {
        return new BloggsApptEncoder();
    }

    function getTtdEncoder()
    {
        return new BloggsTtdEncoder();
    }

    function getConteactEncoder()
    {
        return new BloggsConteactEncoder();
    }

    function getFootText()
    {
        return "BloggsCal footer\n";
    }
}

在這裏,咱們用了工廠模式(目錄在最後)。設計模式之間常常這樣協做,一個模式的建立,能夠成爲另外一個模式的一部分中間件

這方面的想法就是源於模式自己:他是通過無數次同條件下,實踐得出的最優解——將來若是有更好的條件,這個最優解就仍然有優化的空間 / 或者沒有存在的。

結果

模式的意義:

  1. 完全的將 業務需求 與 實現細節 分割,如今,咱們能夠隨意的改動編碼格式,而不用擔憂業務層產生BUG;

  2. 經過強制整合,全部Blogger格式的內容,都經過Blogger建立者類來實現,不會出錯;

  3. 固然,添加新產品則是使人苦惱的,爲了建立新產品的具體實現,咱們必須修改抽象建立者、和他的每個具體實現。

PHP目前尚未強制規定 方法的返回類型,這產生了一些額外的靈活性。(強制規定返回類型,通常爲JAVA之類的 強類型-面向對象-語言)

abstract class CommsManager {
    const APPT    = 1;
    const TTD     = 2;
    const CONTACT = 3;
    abstract function getHeaderText();
    abstract function mark( $flag_int );
    abstract function getFootText();
}

class BloggsCommsManager extends CommsManager {
    function getHeaderText()
    {
        return "BloggsCal header\n";
    }

    function mark( $flag_int )
    {
        switch ($flag_int) {
            case self::APPT:
                return new BloggsApptEncoder();
            case self::TTD:
                return new BloggsTtdEncoder();
            case self::CONTACT:
                return new BloggsConteactEncoder();
        }
    }

    function getFootText()
    {
        return "BloggsCal footer\n";
    }
}

類的接口變得更加緊湊,但也有必定的代價,咱們放棄了詳細的數據格式方法,而是將其中心化了,客戶沒法確認是否實現了須要的具體產品。
因此,也要慎用~

當你的項目中,產品愈來愈多,建立者的數量也隨之臃腫,下一篇將介紹抽象工廠方法的變體:原型模式,這種模式能夠減小必須建立的類。

面向對象設計模式 - 目錄

相關文章
相關標籤/搜索