PHP設(shè)計(jì)模式—?jiǎng)?chuàng)建型設(shè)計(jì)模式

** 創(chuàng)建型設(shè)計(jì)模式 **:

  • 單例模式(Singleton Pattern)
  • 工廠方法模式(Factor Pattern)
  • 抽象工廠模式( Abstract Factor Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)

抽象工廠模式就好比工廠方法模式的升級(jí)版幻赚,所以本文把工廠方法模式和抽象工廠模式混在一起講了


一.單例模式(Singleton Pattern)


單例模式(Singleton Pattern):顧名思義苹熏,就是只有一個(gè)實(shí)例。作為對(duì)象的創(chuàng)建模式,單例模式確保某一個(gè)類只有一個(gè)實(shí)例光督,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例掩幢。

(一)為什么要使用PHP單例模式

1已烤,php的應(yīng)用主要在于數(shù)據(jù)庫應(yīng)用, 一個(gè)應(yīng)用中會(huì)存在大量的數(shù)據(jù)庫操作, 在使用面向?qū)ο蟮姆绞介_發(fā)時(shí), 如果使用單例模式,
則可以避免大量的new 操作消耗的資源,還可以減少數(shù)據(jù)庫連接這樣就不容易出現(xiàn) too many connections情況磁玉。

2,如果系統(tǒng)中需要有一個(gè)類來全局控制某些配置信息, 那么使用單例模式可以很方便的實(shí)現(xiàn). 這個(gè)可以參看zend Framework的FrontController部分中鼠。

3可婶,在一次頁面請(qǐng)求中, 便于進(jìn)行調(diào)試, 因?yàn)樗械拇a(例如數(shù)據(jù)庫操作類db)都集中在一個(gè)類中, 我們可以在類中設(shè)置鉤子, 輸出日志,從而避免到處var_dump, echo

(二)單例模式結(jié)構(gòu)圖

Singleton Pattern

(三)單例模式的實(shí)現(xiàn)

1援雇,私有化一個(gè)屬性用于存放唯一的一個(gè)實(shí)例

2矛渴,私有化構(gòu)造方法,私有化克隆方法惫搏,用來創(chuàng)建并只允許創(chuàng)建一個(gè)實(shí)例

3具温,公有化靜態(tài)方法,用于向系統(tǒng)提供這個(gè)實(shí)例

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

class Singleton{
        //存放實(shí)例
        private static $_instance = null;

        //私有化構(gòu)造方法筐赔、
        private function __construct(){
            echo "單例模式的實(shí)例被構(gòu)造了";
        }
        //私有化克隆方法
        private function __clone(){

        }

        //公有化獲取實(shí)例方法
        public static function getInstance(){
            if (!(self::$_instance instanceof Singleton)){
                self::$_instance = new Singleton();
            }
            return self::$_instance;
        }
    }

    $singleton=Singleton::getInstance();

優(yōu)點(diǎn):因?yàn)殪o態(tài)方法可以在全局范圍內(nèi)被訪問铣猩,當(dāng)我們需要一個(gè)單例模式的對(duì)象時(shí),只需調(diào)用getInstance方法茴丰,獲取先前實(shí)例化的對(duì)象达皿,無需重新實(shí)例化。

(五)使用Trait關(guān)鍵字實(shí)現(xiàn)類似于繼承單例類的功能

Trait是PHP5.4后加入到特性贿肩,有些書說是為了實(shí)現(xiàn)類似C++多重繼承的功能峦椰。Trait定義的代碼結(jié)構(gòu)和類很相似。又有點(diǎn)像實(shí)現(xiàn)邏輯代碼的接口汰规。當(dāng)使用use的時(shí)候汤功,Trait的代碼就好像拷貝到use所在的位置取代use。從這個(gè)角度來看溜哮,更像C的宏定義滔金。

Trait Singleton{
        //存放實(shí)例
        private static $_instance = null;
        //私有化克隆方法
        private function __clone(){

        }

        //公有化獲取實(shí)例方法
        public static function getInstance(){
            $class = __CLASS__;
            if (!(self::$_instance instanceof $class)){
                self::$_instance = new $class();
            }
            return self::$_instance;
        }
    }

class DB {
    private function __construct(){
        echo __CLASS__.PHP_EOL;
    }
}

class DBhandle extends DB {
    use Singleton;
    private function __construct(){
        echo "單例模式的實(shí)例被構(gòu)造了";
    }
}
$handle=DBhandle::getInstance();

//注意若父類方法為public,則子類只能為pubic茬射,
//若父類為private鹦蠕,子類為public 冒签,protected在抛,private都可以。

補(bǔ)充萧恕,大多數(shù)書籍介紹單例模式刚梭,都會(huì)講三私一公肠阱,公優(yōu)化靜態(tài)方法作為提供對(duì)象的接口,私有屬性用于存放唯一一個(gè)單例對(duì)象朴读。私有化構(gòu)造方法屹徘,私有化克隆方法保證只存在一個(gè)單例。

但實(shí)際上衅金,雖然我們無法通過new 關(guān)鍵字和clone出一個(gè)新的對(duì)象噪伊,但我們?nèi)粝氲玫揭粋€(gè)新對(duì)象。還是有辦法的氮唯,那就是通過序列化和反序列化得到一個(gè)對(duì)象鉴吹。私有化__sleep()__wakeup()方法依然無法阻止通過這種方法得到一個(gè)新對(duì)象〕土穑或許真得要阻止豆励,你只能去__wakeup添加刪除一個(gè)實(shí)例的代碼,保證反序列化增加一個(gè)對(duì)象瞒渠,你就刪除一個(gè)良蒸。不過這樣貌似有點(diǎn)怪異。

單例模式也細(xì)分為懶漢模式餓漢模式伍玖,感興趣的朋友可以去了解一下嫩痰。上面的代碼實(shí)現(xiàn)是懶漢模式


二、工廠模式(Factor Pattern)與抽象工廠模式( Abstract Factor Pattern)


工廠模式(Factor Pattern)窍箍,就是負(fù)責(zé)生成其他對(duì)象的類或方法始赎,也叫工廠方法模式

抽象工廠模式( Abstract Factor Pattern),可簡單理解為工廠模式的升級(jí)版

(一)為什么需要工廠模式

1仔燕,工廠模式可以將對(duì)象的生產(chǎn)從直接new 一個(gè)對(duì)象造垛,改成通過調(diào)用一個(gè)工廠方法生產(chǎn)。這樣的封裝晰搀,代碼若需修改new的對(duì)象時(shí)五辽,不需修改多處new語句,只需更改生產(chǎn)對(duì)象方法外恕。

2杆逗,若所需實(shí)例化的對(duì)象可選擇來自不同的類,可省略if-else多層判斷鳞疲,給工廠方法傳入對(duì)應(yīng)的參數(shù)罪郊,利用多態(tài)性,實(shí)例化對(duì)應(yīng)的類尚洽。

(二)工廠模式結(jié)構(gòu)圖

1悔橄,工廠方法模式

Factor Pattern

2,抽象工廠模式

Abstract Factor Pattern

(三)簡單實(shí)現(xiàn)代碼

//工廠類
class Factor{   
    //生成對(duì)象方法
    static function createDB(){
        echo '我生產(chǎn)了一個(gè)DB實(shí)例';
        return new DB;
    }
}

//數(shù)據(jù)類
class DB{
    public function __construct(){
        echo __CLASS__.PHP_EOL;
    }
}

$db=Factor::createDB();

(四)實(shí)現(xiàn)一個(gè)運(yùn)算器

//抽象運(yùn)算類
abstract class Operation{
    abstract public function getVal($i,$j);//抽象方法不能包含方法體
}
//加法類
class OperationAdd extends Operation{
    public function getVal($i,$j){
        return $i+$j;
    }
}
//減法類
class OperationSub extends Operation{
    public function getVal($i,$j){
        return $i-$j;
    }
}

//計(jì)數(shù)器工廠
class CounterFactor {
    private static $operation;
    //工廠生產(chǎn)特定類對(duì)象方法
    static function createOperation(string $operation){
        switch($operation){
            case '+' : self::$operation = new OperationAdd;
                break;
            case '-' : self::$operation = new OperationSub;
                break;
        }
        return self::$operation;
    }
}

$counter = CounterFactor::createOperation('+');
echo $counter->getVal(1,2);

缺點(diǎn):若是再增加一個(gè)乘法運(yùn)算,除了增加一個(gè)乘法運(yùn)算類之外癣疟,還得去工廠生產(chǎn)方法里面添加對(duì)應(yīng)的case代碼挣柬,違反了開放-封閉原則。

解決方法(1):通過傳入指定類名

//計(jì)算器工廠
class CounterFactor {
    //工廠生產(chǎn)特定類對(duì)象方法
    static function createOperation(string $operation){
        return new $operation;
    }
}
class OperationMul extends Operation{
    public function getVal($i,$j){
        return $i*$j;
    }
}
$counter = CounterFactor::createOperation('OperationMul');

解決方法(2):通過抽象工廠模式

這里順帶提一個(gè)問題:如果我系統(tǒng)還有個(gè)生產(chǎn)一個(gè)文本輸入器工廠睛挚,那么那個(gè)工廠和這個(gè)計(jì)數(shù)器工廠又有什么關(guān)系呢邪蛔。

抽象高于實(shí)現(xiàn)

其實(shí)我們完全可以抽象出一個(gè)抽象工廠,然后將對(duì)應(yīng)的對(duì)象生產(chǎn)交給子工廠實(shí)現(xiàn)扎狱。代碼如下

//抽象運(yùn)算類
abstract class Operation{
    abstract public function getVal($i,$j);//抽象方法不能包含方法體
}
//加法類
class OperationAdd extends Operation{
    public function getVal($i,$j){
        return $i+$j;
    }
}
//乘法類
class OperationMul extends Operation{
    public function getVal($i,$j){
        return $i*$j;
    }
}
//抽象工廠類
abstract class Factor{
    abstract static function getInstance();
}
//加法器生產(chǎn)工廠
class AddFactor extends Factor {
    //工廠生產(chǎn)特定類對(duì)象方法
    static function getInstance(){
        return new OperationAdd;
    }
}
//減法器生產(chǎn)工廠
class MulFactor extends Factor {
    static function getInstance(){
        return new OperationMul;
    }
}
//文本輸入器生產(chǎn)工廠
class TextFactor extends Factor{
    static function getInstance(){}
}
$mul = MulFactor::getInstance();
echo $mul->getVal(1,2);

三侧到、建造者模式(Builder Pattern)


建造者模式(Builder Pattern):將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示淤击。

建造者模式是一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象床牧,它允許用戶只通過指定復(fù)雜對(duì)象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)遭贸。建造者模式屬于對(duì)象創(chuàng)建型模式戈咳。根據(jù)中文翻譯的不同,建造者模式又可以稱為生成器模式壕吹。

(一)為什么需要建造者模式
1著蛙,對(duì)象的生產(chǎn)需要復(fù)雜的初始化,比如給一大堆類成員屬性賦初值耳贬,設(shè)置一下其他的系統(tǒng)環(huán)境變量踏堡。使用建造者模式可以將這些初始化工作封裝起來。
2咒劲,對(duì)象的生成時(shí)可根據(jù)初始化的順序或數(shù)據(jù)不同顷蟆,而生成不同角色。

(二)建造者模式結(jié)構(gòu)圖

Builder Pattern

(三)模式應(yīng)用
在很多游戲軟件中腐魂,地圖包括天空帐偎、地面、背景等組成部分蛔屹,人物角色包括人體削樊、服裝、裝備等組成部分兔毒,可以使用建造者模式對(duì)其進(jìn)行設(shè)計(jì)漫贞,通過不同的具體建造者創(chuàng)建不同類型的地圖或人物

(四)設(shè)計(jì)實(shí)例
如果我們想創(chuàng)造出有一個(gè)person類,我們通過實(shí)例化時(shí)設(shè)置的屬性不同育叁,讓他們兩人一個(gè)是速度快的小孩迅脐,一個(gè)是知識(shí)深的長者

class person {
    public $age;
    public $speed;
    public $knowledge;
}
//抽象建造者類
abstract class Builder{
    public $_person;
    public abstract function setAge();
    public abstract function setSpeed();
    public abstract function setKnowledge();
    public function __construct(Person $person){
        $this->_person=$person;
    }
    public function getPerson(){
        return $this->_person;
    }
}
//長者建造者
class OlderBuider extends Builder{
    public function setAge(){
        $this->_person->age=70;
    }
    public function setSpeed(){
        $this->_person->speed="low";
    }
    public function setKnowledge(){
        $this->_person->knowledge='more';
    }
}
//小孩建造者
class ChildBuider extends Builder{
    public function setAge(){
        $this->_person->age=10;
    }
    public function setSpeed(){
        $this->_person->speed="fast";
    }
    public function setKnowledge(){
        $this->_person->knowledge='litte';
    }
}
//建造指揮者
class Director{
    private $_builder;
    public function __construct(Builder $builder){
        $this->_builder = $builder;
    }
    public function built(){
        $this->_builder->setAge();
        $this->_builder->setSpeed();
        $this->_builder->setKnowledge();
    }
}
//實(shí)例化一個(gè)長者建造者
$oldB = new OlderBuider(new Person);
//實(shí)例化一個(gè)建造指揮者
$director = new Director($oldB);
//指揮建造
$director->built();
//得到長者
$older = $oldB->getPerson();

var_dump($older);

(五)總結(jié)

使用建造者模式時(shí),我們把創(chuàng)建一個(gè)person實(shí)例的過程分為了兩步.

一步是先交給對(duì)應(yīng)角色的建造者豪嗽,如長者建造者谴蔑。這樣的好處就把角色的屬性設(shè)置封裝了起來豌骏,我們不用在new一個(gè)person時(shí),因?yàn)橐玫揭粋€(gè)older角色的實(shí)例树碱,而在外面寫了一堆$older->age=70肯适。

另一步是交給了一個(gè)建造指揮者变秦,調(diào)了一個(gè)built方法成榜,通過先設(shè)置age,再設(shè)置Speed的順序蹦玫,初始化這個(gè)角色赎婚。當(dāng)然在這個(gè)例子中,初始化的順序樱溉,是無所謂的挣输。但是如果對(duì)于一個(gè)建造漢堡,或是地圖福贞,初始化的順序不同撩嚼,可能就會(huì)得到不同的結(jié)果。

也許挖帘,你會(huì)說完丽,我直接設(shè)置也很方便呀。是的拇舀,對(duì)于某些情況是這樣的逻族。但是如果你考慮,我現(xiàn)在想增加一個(gè)青年人角色呢骄崩?如果我現(xiàn)在想讓建造有初始化有三種不同的順序呢聘鳞?

如果你使用了建造者模式,這兩個(gè)問題就簡單了要拂,增加一個(gè)青年人角色抠璃,那就增加一個(gè)青年年建造者類。初始化三種不同的順序脱惰,那么就在指揮建造者中增加兩種建造方法鸡典。


原型模式(Prototype Pattern)


原型模式(Prototype Pattern):與工廠模式類似,都是用來創(chuàng)建對(duì)象的枪芒。利用克隆來生成一個(gè)大對(duì)象彻况,減少創(chuàng)建時(shí)的初始化等操作占用開銷

(一)為什么需要原型模式

1,有些時(shí)候舅踪,我們需要?jiǎng)?chuàng)建多個(gè)類似的大對(duì)象纽甘。如果直接通過new對(duì)象,開銷很大抽碌,而且new完還得進(jìn)行重復(fù)的初始化工作悍赢【鐾可能把初始化工作封裝起來的,但是對(duì)于系統(tǒng)來說左权,你封不封裝皮胡,初始化工作還是要執(zhí)行。,

2赏迟,原型模式則不同屡贺,原型模式是先創(chuàng)建好一個(gè)原型對(duì)象,然后通過clone這個(gè)原型對(duì)象來創(chuàng)建新的對(duì)象锌杀,這樣就免去了重復(fù)的初始化工作甩栈,系統(tǒng)僅需內(nèi)存拷貝即可。

(二)原型模式結(jié)構(gòu)圖

Prototype Pattern

(三)簡單實(shí)例

如果說糕再,我們現(xiàn)在正開發(fā)一個(gè)游戲量没,有不同的地圖,地圖大小都是一樣的突想,并且都有海洋殴蹄,但是不同的地圖溫度不一樣。

<?php
//抽象原型類
Abstract class Prototype{
    abstract function __clone();
}
//具體原型類
class Map extends Prototype{
    public $width;
    public $height;
    public $sea;
    public function setAttribute(array $attributes){
        foreach($attributes as $key => $val){
            $this->$key = $val;
        }
    }
    public function __clone(){}
}
//海洋類.這里就不具體實(shí)現(xiàn)了猾担。
class Sea{}

//使用原型模式創(chuàng)建對(duì)象方法如下
//先創(chuàng)建一個(gè)原型對(duì)象
$map_prototype = new Map;
$attributes = array('width'=>40,'height'=>60,'sea'=>(new Sea));
$map_prototype->setAttribute($attributes);
//現(xiàn)在已經(jīng)創(chuàng)建好原型對(duì)象了袭灯。如果我們要?jiǎng)?chuàng)建一個(gè)新的map對(duì)象只需要克隆一下
$new_map = clone $map_prototype;

var_dump($map_prototype);
var_dump($new_map);

通過上面的代碼,我們可以發(fā)現(xiàn)利用原型模式垒探,只需要實(shí)例化并初始化一個(gè)地圖原型對(duì)象妓蛮。以后生產(chǎn)一個(gè)地圖對(duì)象,都可以直接通過clone原型對(duì)象產(chǎn)生圾叼。省去了重新初始化的過程蛤克。

但是上面的代碼還是存在一些問題。那就是它只是一個(gè)淺拷貝夷蚊,什么意思呢构挤?map原型對(duì)象有一個(gè)屬性sea存放了一個(gè)sea對(duì)象,在調(diào)用setAttribute的時(shí)候惕鼓,對(duì)象的賦值方式默認(rèn)是引用筋现。而當(dāng)我們克隆map對(duì)象時(shí),直接克隆了map的sea屬性箱歧,這就使得克隆出來的對(duì)象與原型對(duì)象的sea屬性對(duì)指向了矾飞,同一個(gè)sea對(duì)象的內(nèi)存空間。如果這個(gè)時(shí)候呀邢,我們改變了克隆對(duì)象的sea屬性洒沦,那么原型對(duì)象的sea屬性也跟著改變。

這顯然是不合理的价淌,我們想要的結(jié)果應(yīng)該是深拷貝申眼,也就是改變克隆對(duì)象的所有屬性瞒津,包括用來存放sea這種其他對(duì)象的屬性時(shí),也不影響原型對(duì)象括尸。
當(dāng)然巷蚪,講到這里你可以當(dāng)我在胡說。但我還是建議你打印下原型對(duì)象和克隆對(duì)象濒翻,看一下他們的sea屬性吧屁柏,然后去好好了解一下什么叫深拷貝淺拷貝

(三)深拷貝的實(shí)現(xiàn)

深拷貝的實(shí)現(xiàn)肴焊,其實(shí)也簡單前联,我們只要實(shí)現(xiàn)Map類的克隆方法就行了功戚。這就是我們?yōu)槭裁匆x一個(gè)抽象原型類的原因娶眷。我們利用抽象類,強(qiáng)制所有繼承的具體原型類都必須來實(shí)現(xiàn)這個(gè)克隆方法啸臀。改進(jìn)如下:

//具體原型類
class Map extends Prototype{
    public $width;
    public $height;
    public $sea;
    public function setAttribute(array $attributes){
        foreach($attributes as $key => $val){
            $this->$key = $val;
        }
    }
     //實(shí)現(xiàn)克隆方法届宠,用來實(shí)現(xiàn)深拷貝
    public function __clone(){
        $this->sea = clone $this->sea;
    }
}

到這里原型模式就算實(shí)現(xiàn)了,但是我覺還可以進(jìn)一步進(jìn)行封裝响驴,利用工廠模式或建造者模式的思想阀湿。

(四)延伸

舉個(gè)例子蝠嘉,如果我們?cè)诳寺∵@個(gè)地圖對(duì)象的同時(shí)我們還需要進(jìn)行一下系統(tǒng)設(shè)置,或是說我們想給原型對(duì)象的clone_id屬性賦值當(dāng)前已經(jīng)拷貝了多少個(gè)對(duì)象的總數(shù)量轧铁?

我們可以把clone這個(gè)動(dòng)作封裝到一個(gè)類似的工廠方法里面去,簡單地實(shí)現(xiàn)一下旦棉,雖然不咋嚴(yán)謹(jǐn)齿风。

<?php
//抽象原型類
Abstract class Prototype{
    abstract function __clone();
}
//具體原型類
class Map extends Prototype{
    public $clone_id=0;
    public $width;
    public $height;
    public $sea;
    public function setAttribute(array $attributes){
        foreach($attributes as $key => $val){
            $this->$key = $val;
        }
    }
    //實(shí)現(xiàn)克隆方法,用來實(shí)現(xiàn)深拷貝
    public function __clone(){
        $this->sea = clone $this->sea;
    }
}
//海洋類.這里就不具體實(shí)現(xiàn)了绑洛。
class Sea{}
//克隆機(jī)器
class CloneTool{
    static function clone($instance,$id){
        $instance->clone_id ++;
        system_write(get_class($instance));
        return clone $instance;
    }
}
//系統(tǒng)通知函數(shù)
function system_write($class){
    echo "有人使用克隆機(jī)器克隆了一個(gè){$class}對(duì)象".PHP_EOL;
}

//使用原型模式創(chuàng)建對(duì)象方法如下
//先創(chuàng)建一個(gè)原型對(duì)象
$map_prototype = new Map;
$attributes = array('width'=>40,'height'=>60,'sea'=>(new Sea));
$map_prototype->setAttribute($attributes);
//現(xiàn)在已經(jīng)創(chuàng)建好原型對(duì)象了救斑。如果我們要?jiǎng)?chuàng)建一個(gè)新的map對(duì)象只需要克隆一下
$new_map = CloneTool::clone($map_prototype,1);

var_dump($map_prototype);
var_dump($new_map);

(五)模型應(yīng)用

多用于創(chuàng)建大對(duì)象,或初始化繁瑣的對(duì)象真屯。如游戲中的背景脸候,地圖。web中的畫布等等


五绑蔫、創(chuàng)建型設(shè)計(jì)模式雜談


  1. 單例模式运沦,工廠模式,建造者模式配深,原型模式都屬于創(chuàng)建型模式携添。使用創(chuàng)建型模式的目的,就是為了創(chuàng)建一個(gè)對(duì)象凉馆。

  2. 創(chuàng)建型模式的優(yōu)點(diǎn)薪寓,在于如何把復(fù)雜的創(chuàng)建過程封裝起來亡资,如何降低系統(tǒng)的內(nèi)銷。

  3. 我認(rèn)為創(chuàng)建型模式的一個(gè)總要的思想其實(shí)就是封裝向叉,利用封裝锥腻,把直接獲得一個(gè)對(duì)象改為通過一個(gè)接口獲得一個(gè)對(duì)象。這樣最明顯的優(yōu)點(diǎn)母谎,在于我們可以把一些復(fù)雜的操作也封裝到接口里去瘦黑,我們使用時(shí)直接調(diào)這個(gè)接口就可以了。具體的實(shí)現(xiàn)奇唤,我們?cè)谥骶€程序中就不再考慮幸斥。這樣使得我們的代碼看上去更少,更簡潔咬扇。

  4. 單例模式甲葬,我們把對(duì)象的生成從new改為通過一個(gè)靜態(tài)方法,通過靜態(tài)方法的控制懈贺,使得我們總是返回同一個(gè)實(shí)例給調(diào)用者经窖,確保了系統(tǒng)只有一個(gè)實(shí)例

  5. 工廠模式,也是一樣梭灿,生成對(duì)象改為接口画侣,還可以通過傳參實(shí)例化不同的類。如果我們通過直接new的話堡妒,那么我們?cè)谥骶€代碼中少不了要寫if condition new 一個(gè)加法類配乱,else new一個(gè)減法類。封裝了之后皮迟,我們通過接口傳參搬泥,還能利用多態(tài)的特性去替代if else語句。
    而且我們遵循了單一原則万栅,讓類的功能單一佑钾。我們?nèi)绻枰粋€(gè)新功能,只需添加一個(gè)類烦粒,不用修改其他類的功能休溶。這樣使得代碼的擴(kuò)展性更好了。

  6. 建造者模式扰她,我們把初始化的工作和順序兽掰,封裝給了一個(gè)建造者和指揮者。如果徒役,我們下次要建造的類屬性孽尽,或是順序不同。我們只需新建對(duì)應(yīng)的建造者類或添加對(duì)應(yīng)的指揮者方法忧勿,不必再去修改原代碼杉女。而且我們也省去了瞻讽,這new對(duì)象后,還要寫$attribut=array();這種一大串?dāng)?shù)組熏挎,然后調(diào)好幾個(gè)方法去初始化的工作速勇。

  7. 原型模式,通過先創(chuàng)建一個(gè)原型對(duì)象坎拐,然后直接克隆烦磁,省去了new大對(duì)象帶來的開銷浪費(fèi)。當(dāng)然我們同樣可以通過哼勇,封裝clone這個(gè)動(dòng)作都伪。使得我們?cè)赾lone的同時(shí)還可以做一些其他的準(zhǔn)備工作。


感謝閱讀积担,由于筆者也是初學(xué)設(shè)計(jì)模式陨晶,能力有限,文章不可避免地有失偏頗
后續(xù)更新** PHP設(shè)計(jì)模式-結(jié)構(gòu)型設(shè)計(jì)模式 **介紹磅轻,歡迎大家評(píng)論指正


我最近的學(xué)習(xí)總結(jié):


歡迎大家關(guān)注我的微信公眾號(hào) 火風(fēng)鼎
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末珍逸,一起剝皮案震驚了整個(gè)濱河市逐虚,隨后出現(xiàn)的幾起案子聋溜,更是在濱河造成了極大的恐慌,老刑警劉巖叭爱,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撮躁,死亡現(xiàn)場離奇詭異,居然都是意外死亡买雾,警方通過查閱死者的電腦和手機(jī)把曼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漓穿,“玉大人嗤军,你說我怎么就攤上這事』挝#” “怎么了叙赚?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長僚饭。 經(jīng)常有香客問我震叮,道長,這世上最難降的妖魔是什么鳍鸵? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任苇瓣,我火速辦了婚禮,結(jié)果婚禮上偿乖,老公的妹妹穿的比我還像新娘击罪。我一直安慰自己哲嘲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布媳禁。 她就那樣靜靜地躺著撤蚊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪损话。 梳的紋絲不亂的頭發(fā)上侦啸,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音丧枪,去河邊找鬼光涂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拧烦,可吹牛的內(nèi)容都是我干的忘闻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼恋博,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼齐佳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起债沮,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤炼吴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后疫衩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硅蹦,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年闷煤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了童芹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鲤拿,死狀恐怖假褪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情近顷,我是刑警寧澤生音,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站幕庐,受9級(jí)特大地震影響久锥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜异剥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一瑟由、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦歹苦、人聲如沸青伤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狠角。三九已至,卻和暖如春蚪腋,著一層夾襖步出監(jiān)牢的瞬間丰歌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工屉凯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留立帖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓悠砚,卻偏偏與公主長得像晓勇,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灌旧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式匯總 一绑咱、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,903評(píng)論 1 15
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理枢泰,服務(wù)發(fā)現(xiàn)描融,斷路器,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 前段時(shí)間宗苍,在自己糊里糊涂地寫了一年多的代碼之后稼稿,接手了一坨一個(gè)同事的代碼。身邊很多人包括我自己都在痛罵那些亂糟糟毫...
    丑小丫大笨蛋閱讀 623評(píng)論 0 2
  • 創(chuàng)建型模式 抽象工廠模式(abstract facroty) 3.1模式動(dòng)機(jī) 在工廠方法模式中具體工廠負(fù)責(zé)生產(chǎn)具體...
    僚機(jī)KK閱讀 722評(píng)論 0 2
  • ffffrtt閱讀 94評(píng)論 0 0