日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

PHP設(shè)計(jì)模式之模板方法模式

 硬核項(xiàng)目經(jīng)理 2021-05-31

PHP設(shè)計(jì)模式之模板方法模式

模板方法模式,也是我們經(jīng)常會(huì)在不經(jīng)意間有會(huì)用到的模式之一。這個(gè)模式是對(duì)繼承的最好詮釋。當(dāng)子類中有重復(fù)的動(dòng)作時(shí),將他們提取出來(lái),放在父類中進(jìn)行統(tǒng)一的處理,這就是模板方法模式的最簡(jiǎn)單通俗的解釋。就像我們平時(shí)做項(xiàng)目,每次的項(xiàng)目流程實(shí)都差不多,都有調(diào)研、開(kāi)發(fā)、測(cè)試、部署上線等流程。而具體到每個(gè)項(xiàng)目中,這些流程的實(shí)現(xiàn)又不會(huì)完全相同。這個(gè)流程,就像是模板方法,讓我們每次都按照這個(gè)流程進(jìn)行開(kāi)發(fā)。

Gof類圖及解釋

GoF定義:定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

GoF類圖

代碼實(shí)現(xiàn)

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

abstract public function PrimitiveOperation1();
abstract public function PrimitiveOperation2();
}

定義一個(gè)抽象類,有一個(gè)模板方法TemplateMethod(),這個(gè)方法中我們對(duì)算法操作方法進(jìn)行調(diào)用。而這些算法抽象方法是在子類中去實(shí)現(xiàn)的。

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

class ConcreteClassB extends AbstractClass
{
public function PrimitiveOperation1()
{
echo '具體類B實(shí)現(xiàn)方法1', PHP_EOL;
}
public function PrimitiveOperation2()
{
echo '具體類B實(shí)現(xiàn)方法2', PHP_EOL;
}
}

具體的實(shí)現(xiàn)類,它們只需要去實(shí)現(xiàn)父類所定義的算法就可以了。

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

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

在客戶端的調(diào)用中,實(shí)例化子類,但調(diào)用的是子類所繼承的父類的模板方法。就可以實(shí)現(xiàn)統(tǒng)一的算法調(diào)用了。

  • 模板方法模式相信只要是做過(guò)一點(diǎn)面向?qū)ο箝_(kāi)發(fā)的朋友都會(huì)多多少少使用過(guò)。因?yàn)檎娴姆浅3R?jiàn)

  • 一些框架中經(jīng)常會(huì)有某些功能類有初始化的功能,在初始化的函數(shù)中都會(huì)調(diào)用很多內(nèi)部的其他函數(shù),這其實(shí)也是一種模板方法模式的應(yīng)用

  • 模板方法模式可以很方便的實(shí)現(xiàn)鉤子函數(shù)。就像很多模板或者開(kāi)源系統(tǒng)中給你準(zhǔn)備好的鉤子函數(shù)。比如某些博客開(kāi)源程序會(huì)預(yù)留一些廣告位或者特殊位置的鉤子函數(shù)讓使用者自己按需實(shí)現(xiàn)

  • 模板方法模式適用于:一次性實(shí)現(xiàn)一個(gè)算法中不變的部分,并將可變的部分留給子類來(lái)實(shí)現(xiàn);將子類中公共的行為提取出來(lái)并集中到父類中;控制子類的擴(kuò)展;

  • 這個(gè)模式體現(xiàn)了一個(gè)叫“好萊塢法則”的原則,那就是“別找我們,我們來(lái)找你”

在公司中,我非常的推崇敏捷式的項(xiàng)目管理,當(dāng)然,這里也不是說(shuō)傳統(tǒng)的項(xiàng)目管理有多么不好,只是敏捷更適合我們這種短平快的公司。在敏捷中,我們采用的是Scurm框架,它其實(shí)就是一個(gè)模板。它定義了四種會(huì)議、三種人員、三個(gè)工具。在每個(gè)項(xiàng)目的具體實(shí)現(xiàn)中,我們都會(huì)遵守這些規(guī)則,但具體的實(shí)現(xiàn)又不會(huì)一樣。比如有時(shí)我們是一周一個(gè)迭代,有時(shí)是一個(gè)月一個(gè)迭代。有時(shí)我們不需要回顧會(huì)議,而是將回顧和評(píng)審會(huì)議放在了一起進(jìn)行。不管怎么樣,我們會(huì)在Scurm的基礎(chǔ)上進(jìn)行靈活的項(xiàng)目開(kāi)發(fā)。而做為領(lǐng)導(dǎo)的我,只需要在每個(gè)項(xiàng)目中調(diào)取Scurm的基本流程就可以了。所以說(shuō),公司的強(qiáng)大和大家的學(xué)習(xí)是分不開(kāi)的,好用的東西當(dāng)然要時(shí)刻學(xué)習(xí)分享并應(yīng)用啦?。?/em>

完整代碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/20.template-method/source/template-method.php

實(shí)例

不發(fā)短信了,這次我們實(shí)現(xiàn)的是一個(gè)Cache類的初始化部分。就像上文說(shuō)過(guò)的一些框架中的工具類。一般Cache我們會(huì)使用Memcached或者Redis來(lái)實(shí)現(xiàn),所以我們抽取一個(gè)公共Cache類,然后讓Memcached和Redis的Cache實(shí)現(xiàn)類都繼承它。在公共類中,通過(guò)模板方法來(lái)進(jìn)行實(shí)現(xiàn)類的一些初始化工作,這些工作由父類統(tǒng)一調(diào)用,實(shí)現(xiàn)類只需要實(shí)現(xiàn)每一個(gè)步驟的具體內(nèi)容就可以了。

緩存類圖

完整源碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/20.template-method/source/template-method-cache.php

<?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連接失敗,請(qǐng)檢查配置項(xiàng)!', 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連接失敗,請(qǐng)檢查配置項(xiàng)!', PHP_EOL;
}
}
}

$m = new MemcachedCache();

$r = new RedisCache();

說(shuō)明

  • 這樣一個(gè)簡(jiǎn)單的緩存類我們就實(shí)現(xiàn)了。是不是和很多框架中的代碼非常類似。

  • 子類只需要定義自己的實(shí)現(xiàn)就可以了,剩下的重復(fù)代碼都讓父類去完成,如果沒(méi)有父類,它們都需要自己實(shí)現(xiàn)一個(gè)init()方法

  • 當(dāng)然,需要增加其它的實(shí)現(xiàn)類時(shí),也只需要繼承這個(gè)Cache父類后完成自己的實(shí)現(xiàn)就可以了,客戶端面對(duì)這些實(shí)現(xiàn)類都能非常輕松,因?yàn)樗鼈冎雷约褐恍枰日{(diào)用一下初始化方法可以使用這個(gè)類了,不管是哪一個(gè)實(shí)現(xiàn)類都是一樣的

下期看點(diǎn)

模板方法模式是不是也非常簡(jiǎn)單。最主要的是這樣的設(shè)計(jì)模式跟我們的生活很接近,在我們的工作學(xué)習(xí)過(guò)程會(huì)非常容易見(jiàn)到并使用到。這樣的模式簡(jiǎn)直不能掛在常用設(shè)計(jì)模式的標(biāo)簽下,因?yàn)樗瘸S酶S谩:昧?,我們的進(jìn)度還不錯(cuò)喲,下一個(gè)模式正等著我們呢,它可是大名鼎鼎的單例模式。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多