PHP設計模式之模板方法模式

PHP設計模式之模板方法模式

模板方法模式,也是咱們常常會在不經意間有會用到的模式之一。這個模式是對繼承的最好詮釋。當子類中有重複的動做時,將他們提取出來,放在父類中進行統一的處理,這就是模板方法模式的最簡單通俗的解釋。就像咱們平時作項目,每次的項目流程實都差很少,都有調研、開發、測試、部署上線等流程。而具體到每一個項目中,這些流程的實現又不會徹底相同。這個流程,就像是模板方法,讓咱們每次都按照這個流程進行開發。php

Gof類圖及解釋

GoF定義:定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。git

GoF類圖github

模板方法模式

代碼實現redis

abstract class AbstractClass {
    public function TemplateMethod() {
        $this->PrimitiveOperation1();
        $this->PrimitiveOperation2();
    }

    abstract public function PrimitiveOperation1();
    abstract public function PrimitiveOperation2();
}
複製代碼

定義一個抽象類,有一個模板方法TemplateMethod(),這個方法中咱們對算法操做方法進行調用。而這些算法抽象方法是在子類中去實現的。算法

class ConcreteClassA extends AbstractClass {
    public function PrimitiveOperation1() {
        echo '具體類A實現方法1', PHP_EOL;
    }
    public function PrimitiveOperation2() {
        echo '具體類A實現方法2', PHP_EOL;
    }
}

class ConcreteClassB extends AbstractClass {
    public function PrimitiveOperation1() {
        echo '具體類B實現方法1', PHP_EOL;
    }
    public function PrimitiveOperation2() {
        echo '具體類B實現方法2', PHP_EOL;
    }
}
複製代碼

具體的實現類,它們只須要去實現父類所定義的算法就能夠了。設計模式

$c = new ConcreteClassA();
$c->TemplateMethod();

$c = new ConcreteClassB();
$c->TemplateMethod();
複製代碼

在客戶端的調用中,實例化子類,但調用的是子類所繼承的父類的模板方法。就能夠實現統一的算法調用了。緩存

  • 模板方法模式相信只要是作過一點面向對象開發的朋友都會多多少少使用過。由於真的很是常見
  • 一些框架中常常會有某些功能類有初始化的功能,在初始化的函數中都會調用不少內部的其餘函數,這其實也是一種模板方法模式的應用
  • 模板方法模式能夠很方便的實現鉤子函數。就像不少模板或者開源系統中給你準備好的鉤子函數。好比某些博客開源程序會預留一些廣告位或者特殊位置的鉤子函數讓使用者本身按需實現
  • 模板方法模式適用於:一次性實現一個算法中不變的部分,並將可變的部分留給子類來實現;將子類中公共的行爲提取出來並集中到父類中;控制子類的擴展;
  • 這個模式體現了一個叫「好萊塢法則」的原則,那就是「別找咱們,咱們來找你」

在公司中,我很是的推崇敏捷式的項目管理,固然,這裏也不是說傳統的項目管理有多麼很差,只是敏捷更適合咱們這種短平快的公司。在敏捷中,咱們採用的是Scurm框架,它其實就是一個模板。它定義了四種會議、三種人員、三個工具。在每一個項目的具體實現中,咱們都會遵照這些規則,但具體的實現又不會同樣。好比有時咱們是一週一個迭代,有時是一個月一個迭代。有時咱們不須要回顧會議,而是將回顧和評審會議放在了一塊兒進行。無論怎麼樣,咱們會在Scurm的基礎上進行靈活的項目開發。而作爲領導的我,只須要在每一個項目中調取Scurm的基本流程就能夠了。因此說,公司的強大和你們的學習是分不開的,好用的東西固然要時刻學習分享並應用啦!!框架

完整代碼:github.com/zhangyue050…memcached

實例

不發短信了,此次咱們實現的是一個Cache類的初始化部分。就像上文說過的一些框架中的工具類。通常Cache咱們會使用Memcached或者Redis來實現,因此咱們抽取一個公共Cache類,而後讓Memcached和Redis的Cache實現類都繼承它。在公共類中,經過模板方法來進行實現類的一些初始化工做,這些工做由父類統一調用,實現類只須要實現每個步驟的具體內容就能夠了。函數

緩存類圖

緩存模板方法模式版

完整源碼:github.com/zhangyue050…

<?php

abstract class Cache {
    private $config;
    private $conn;

    public function __construct() {
        $this->init();
    }
    public function init() {
        $this->GetConfig();
        $this->OpenConnection();
        $this->CheckConnection();
    }

    abstract public function GetConfig();
    abstract public function OpenConnection();
    abstract public function CheckConnection();
}

class MemcachedCache extends Cache {
    public function GetConfig() {
        echo '獲取Memcached配置文件!', PHP_EOL;
        $this->config = 'memcached';
    }
    public function OpenConnection() {
        echo '連接memcached!', PHP_EOL;
        $this->conn = 1;
    }
    public function CheckConnection() {
        if ($this->conn) {
            echo 'Memcached鏈接成功!', PHP_EOL;
        } else {
            echo 'Memcached鏈接失敗,請檢查配置項!', PHP_EOL;
        }
    }
}

class RedisCache extends Cache {
    public function GetConfig() {
        echo '獲取Redis配置文件!', PHP_EOL;
        $this->config = 'redis';
    }
    public function OpenConnection() {
        echo '連接redis!', PHP_EOL;
        $this->conn = 0;
    }
    public function CheckConnection() {
        if ($this->conn) {
            echo 'Redis鏈接成功!', PHP_EOL;
        } else {
            echo 'Redis鏈接失敗,請檢查配置項!', PHP_EOL;
        }
    }
}

$m = new MemcachedCache();

$r = new RedisCache();

複製代碼

說明

  • 這樣一個簡單的緩存類咱們就實現了。是否是和不少框架中的代碼很是相似。
  • 子類只須要定義本身的實現就能夠了,剩下的重複代碼都讓父類去完成,若是沒有父類,它們都須要本身實現一個init()方法
  • 固然,須要增長其它的實現類時,也只須要繼承這個Cache父類後完成本身的實現就能夠了,客戶端面對這些實現類都能很是輕鬆,由於它們知道本身只須要先調用一下初始化方法可使用這個類了,不論是哪個實現類都是同樣的

下期看點

模板方法模式是否是也很是簡單。最主要的是這樣的設計模式跟咱們的生活很接近,在咱們的工做學習過程會很是容易見到並使用到。這樣的模式簡直不能掛在經常使用設計模式的標籤下,由於它比經常使用更經常使用。好了,咱們的進度還不錯喲,下一個模式正等着咱們呢,它但是大名鼎鼎的單例模式

相關文章
相關標籤/搜索