亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

通俗易懂的談?wù)勓b飾器模式

forsigner / 603人閱讀

摘要:裝飾器模式允許向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。這便是裝飾模式,通過(guò)一層一層的裝飾,我們可以靈活的得到我們想要的結(jié)果??梢暂p松的添加新的裝飾器類或者新的組件來(lái)創(chuàng)建靈活的結(jié)構(gòu)。

前言

在編碼的時(shí)候,我們?yōu)榱藬U(kuò)展一個(gè)類經(jīng)常是使用繼承方式來(lái)實(shí)現(xiàn),隨著擴(kuò)展功能的增多,子類會(huì)越來(lái)越膨脹,使系統(tǒng)變得不靈活。

裝飾器模式( Decorator Pattern )允許向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。它能讓我們?cè)跀U(kuò)展類的時(shí)候讓系統(tǒng)較好的保持靈活性。

那么裝飾器模式具體是什么樣的呢?

從一個(gè)情景開(kāi)始

我們有一塊地,在這塊地上,我們要蓋一棟有好幾間房間的別墅,每間房間的裝修費(fèi)用都不同,現(xiàn)在,我們要對(duì)蓋別墅的費(fèi)用進(jìn)行計(jì)算。

先定義一個(gè)Land類,表示這塊地,Land類定義了在這塊地上蓋別墅需要花錢這個(gè)規(guī)則。

abstract class Land
{
    abstract public function cost();
}

Land已經(jīng)定義好了在這塊地上蓋房需要花錢的這個(gè)規(guī)則了,但是蓋一間房間具體花多少錢呢?

此時(shí)我們?cè)俣x一個(gè)Room類,這個(gè)類具體的定義了一個(gè)房間建造的基本費(fèi)用(一個(gè)最簡(jiǎn)單房間,里面啥也沒(méi)有的)。

class Room extends Land
{
    private $money = 1000;
    public function cost()
    {
        return $this->money;
    }
}

然后開(kāi)始建造房間,我們建了兩個(gè)房間,分別是客廳和餐廳,用LivingRoom類和DiningRoom類來(lái)表示

class LivingRoom extends Room
{
    public function cost()
    {
        return parent::cost()+200; //客廳的建造費(fèi)用在房屋建造費(fèi)用的基礎(chǔ)上多200,比如要買沙發(fā),電視
    }
    
}

class DiningRoom extends Room
{
    public function cost()
    {
        return parent::cost()+100; //餐廳的建造費(fèi)用在房屋建造費(fèi)用的基礎(chǔ)上多100,比如買餐桌
    }
}

現(xiàn)在,我們很容易就能得到建造一間客廳所需的花費(fèi)

$livingRoomCost = new LivingRoom();
echo $livingRoomCost->cost();
問(wèn)題的產(chǎn)生

不過(guò),這樣的結(jié)構(gòu)并不具備靈活性,雖然我們可以很容易的分別得出建造一間客廳和建造一間餐廳的費(fèi)用,但是,如果我買的地比較小,只能把餐廳和客廳建在同一個(gè)房間里,那要怎么去計(jì)算費(fèi)用?難道還要很麻煩的去創(chuàng)建一個(gè)包含客廳和餐廳的LivingDiningRoom類?這樣做的話除了麻煩,還會(huì)使代碼產(chǎn)生重復(fù)。

解決問(wèn)題

為了更好的解決這個(gè)問(wèn)題,我們得做一些調(diào)整,同樣先聲明Land類和Room類,不同的是,引入了一個(gè)房間的裝飾類RoomDecorator,它繼承了Land類,因?yàn)闆](méi)有實(shí)現(xiàn)Land類的cost()方法,所以需將它聲明為抽象類,并且定義了一個(gè)以Land類的對(duì)象為參數(shù)的構(gòu)造方法,傳入的對(duì)象會(huì)保存在$land屬性中,該屬性聲明為protected,以便子類訪問(wèn)。具體如下。

abstract class RoomDecorator extends Land
{
    protected $land;
    public function __construct(Land $land)
    {
        $this->land = $land;
    }
}

然后我們?cè)僦匦露x客廳類和餐廳類

class LivingRoom extends RoomDecorator
{
    public function cost()
    {
        return $this->land->cost()+200;
    }
}


class DiningRoom extends RoomDecorator
{
    public function cost()
    {
        return $this->land->cost()+100;
    }
}

這兩個(gè)類都擴(kuò)展自RoomDecorator類,這意味著它們都擁有指向Land對(duì)象的引用。當(dāng)它們的cost()方法被調(diào)用時(shí),都會(huì)先調(diào)用所引用的Land類對(duì)象的cost()方法,然后再執(zhí)行自己特有的操作。

所以這時(shí)候,建造一間客廳所需的費(fèi)用是這樣計(jì)算

$livingRoomCost = new LivingRoom(new Room());
echo $livingRoomCost->cost(); //輸出1200

建造一間餐廳所需的費(fèi)用是這樣計(jì)算

$diningRoomCost = new DiningRoom(new Room());
echo $diningRoomCost->cost(); //輸出1100

回到剛才的問(wèn)題,如果我們需計(jì)算建造一間包含客廳餐廳的房間所需費(fèi)用,代碼如下

$livingRoom = new DiningRoom(new LivingRoom(new Room()));
echo $livingRoom->cost(); //輸出1300

看,我們現(xiàn)在計(jì)算建造費(fèi)用的思路是:計(jì)算出基礎(chǔ)房間的費(fèi)用 --> 在基礎(chǔ)房間上裝飾成客廳的費(fèi)用 --> 在客廳的基礎(chǔ)上加裝飾餐廳的費(fèi)用 --> 得到包含客廳餐廳的房間費(fèi)用。已經(jīng)不需要麻煩的通過(guò)創(chuàng)建一個(gè)LivingDiningRoom類來(lái)計(jì)算包含客廳餐廳的房間建造費(fèi)用了。

這便是裝飾模式,通過(guò)一層一層的裝飾,我們可以靈活的得到我們想要的結(jié)果??梢暂p松的添加新的裝飾器類或者新的組件來(lái)創(chuàng)建靈活的結(jié)構(gòu)。

完整代碼
money;
    }
}

//裝飾器
abstract class RoomDecorator extends Land
{
    protected $land;
    public function __construct(Land $land)
    {
        $this->land = $land;
    }
}

class LivingRoom extends RoomDecorator
{
    public function cost()
    {
        return $this->land->cost()+200;
    }
}


class DiningRoom extends RoomDecorator
{
    public function cost()
    {
        return $this->land->cost()+100;
    }
}

$livingRoomCost = new LivingRoom(new Room());
echo $livingRoomCost->cost(); //輸出1200

$diningRoomCost = new DiningRoom(new Room());
echo $diningRoomCost->cost(); //輸出1100

$livingDining = new DiningRoom(new LivingRoom(new Room()));
echo $livingDining->cost(); //輸出1300

the end.

happy coding! ^_^

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/25853.html

相關(guān)文章

  • 通俗易懂設(shè)計(jì)模式

    摘要:面向?qū)ο笤O(shè)計(jì)模式通常以類別或?qū)ο髞?lái)描述其中的關(guān)系和相互作用,但不涉及用來(lái)完成應(yīng)用程序的特定類別或?qū)ο?。里氏代換原則里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。 通俗易懂的設(shè)計(jì)模式 零、使用 1、安裝 2、測(cè)試 一、什么是設(shè)計(jì)模式 二、設(shè)計(jì)模式的類型 三、設(shè)計(jì)模式的六大原則 四、UML類圖 1、看懂UML類圖 2、解釋 五、資料 前言:花了一些時(shí)間再次熟悉了一遍...

    wuyangnju 評(píng)論0 收藏0
  • 從Express到Nestjs,談?wù)?/em>Nestjs設(shè)計(jì)思想和使用方法

    摘要:三的洋蔥模型這里簡(jiǎn)單講講在中是如何分層的,也就是說(shuō)請(qǐng)求到達(dá)服務(wù)端后如何層層處理,直到響應(yīng)請(qǐng)求并將結(jié)果返回客戶端。從而使得端支持跨域等。 ??最近已經(jīng)使用過(guò)一段時(shí)間的nestjs,讓人寫(xiě)著有一種java spring的感覺(jué),nestjs可以使用express的所有中間件,此外完美的支持typescript,與數(shù)據(jù)庫(kù)關(guān)系映射typeorm配合使用可以快速的編寫(xiě)一個(gè)接口網(wǎng)關(guān)。本文會(huì)介紹一下作...

    chanjarster 評(píng)論0 收藏0
  • 從Express到Nestjs,談?wù)?/em>Nestjs設(shè)計(jì)思想和使用方法

    摘要:三的洋蔥模型這里簡(jiǎn)單講講在中是如何分層的,也就是說(shuō)請(qǐng)求到達(dá)服務(wù)端后如何層層處理,直到響應(yīng)請(qǐng)求并將結(jié)果返回客戶端。從而使得端支持跨域等。 ??最近已經(jīng)使用過(guò)一段時(shí)間的nestjs,讓人寫(xiě)著有一種java spring的感覺(jué),nestjs可以使用express的所有中間件,此外完美的支持typescript,與數(shù)據(jù)庫(kù)關(guān)系映射typeorm配合使用可以快速的編寫(xiě)一個(gè)接口網(wǎng)關(guān)。本文會(huì)介紹一下作...

    wawor4827 評(píng)論0 收藏0
  • 編程中那些經(jīng)典套路——設(shè)計(jì)模式匯總

    摘要:如果看不懂的話,可以在評(píng)論區(qū)中提問(wèn),我會(huì)第一時(shí)間回答你無(wú)論何時(shí)我一直都在嗯哼該文章屬于編程中的那些經(jīng)典套路設(shè)計(jì)模式匯總系列 在正式閱讀前,我先談?wù)勎覀冊(cè)撚檬裁醋藙?shì)和心態(tài)學(xué)習(xí)設(shè)計(jì)模式: 如果你還沒(méi)有過(guò)多的編程經(jīng)驗(yàn)(泛指半年以下),我建議你把它當(dāng)做小說(shuō)來(lái)看,能看懂多少是多少,因?yàn)榘肽暌韵陆?jīng)驗(yàn)的程序員用到設(shè)計(jì)模式的情況只會(huì)出現(xiàn)在面試上,至于實(shí)際工作中?相對(duì)來(lái)說(shuō)這部分不會(huì)由你負(fù)責(zé)。 如果你已...

    youkede 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<