国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

PHP設計模式之裝飾者模式

2020-03-22 19:04:32
字體:
來源:轉載
供稿:網友

  • 有這樣一個項目,做一個餐廳訂餐系統。起初的代碼結構是這樣的。前面有很多Beverage的繼承類,現在遇到的問題是牛奶的價錢上漲了,那么所有相關的類,我們都要進行調整,比如Milk,SugarAndMilk類,這種類還有很多,我們需要逐個去修改類中的方法——開發人員每次都做這種事情,要瘋了!所以我們要改變現有的結構。以下的圖都是簡圖,實際的圖,可沒有這么簡單。


    設計問題:

    1》類數量爆炸,有很多類,難以維護;

    2》整個設計呆板;

    3》基類加入的新功能無法使用于子類;

    復用類方法的方式很多,比如繼承,組合,委托。為什么老是習慣用繼承呢?我看Zend Framework也有這種習慣!每次找對應方法,一直往上翻。——題外話!!!!

    后來經過小組研究決定,我們決定把基礎類抽出來,比如,我們把咖啡做成一個單獨的類,其他的咖啡,比如牛奶咖啡,甜味咖啡,我們只對材料單獨包裝成一個類。

    經過改良的設計:


    詳解

    1》對于飲品,我們直接繼承Beverage類,直接把報價寫進飲品類里面;

    2》而對于一些需要添加調味品的特殊飲品,我們做累加操作。比如,我想要杯奶咖啡,則 總價=咖啡價+奶價

    3》這樣不同的飲料就很容易知道它的價格。

    <?php abstract html' target='_blank'>class Beverage{     public $_name;     abstract public function Cost(); } // 被裝飾者類 class Coffee extends Beverage{     public function __construct(){         $this->_name = 'Coffee';     }        public function Cost(){         return 1.00;     }    } // 以下三個類是裝飾者相關類 class CondimentDecorator extends Beverage{     public function __construct(){         $this->_name = 'Condiment';     }        public function Cost(){         return 0.1;     }    }   class Milk extends CondimentDecorator{     public $_beverage;     public function __construct($beverage){         $this->_name = 'Milk';         if($beverage instanceof Beverage){             $this->_beverage = $beverage;         }else            exit('Failure');     }        public function Cost(){         return $this->_beverage->Cost() + 0.2;     }    }   class Sugar extends CondimentDecorator{     public $_beverage;     public function __construct($beverage){         $this->_name = 'Sugar';         if($beverage instanceof Beverage){             $this->_beverage = $beverage;         }else{             exit('Failure');         }     }     public function Cost(){         return $this->_beverage->Cost() + 0.2;     } }   // Test Case //1.拿杯咖啡 $coffee = new Coffee();   //2.加點牛奶 $coffee = new Milk($coffee);   //3.加點糖 $coffee = new Sugar($coffee);   printf("Coffee Total:%0.2f元/n",$coffee->Cost());

    1.裝飾者(Milk)和被裝飾者(Coffee)必須是一樣的類型。目的是裝飾者必須取代被裝飾者。
    2.添加行為:當裝飾者和組件組合時,就是在加入新的行為。

    題外話:
    1.利用繼承設計子類行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。打個比方,老子想學點功夫,看你小子會太極拳,老子只需要繼承你一下 ,老子也就會太極拳了——呵呵,這時老子就變成你兒子了,看來繼承是要付出代價的。

    2.組合,我們可以擴展對象的行為,在運行時動態地進行擴展。利用組合我們可以隨時把我們當時設計超類時沒有想到的方法加入到對象中,而不用改變現有的代碼。打個比方,老子現在沒有內力,吸功大法,把和尚,尼姑,道士的內力(行為對象)都吸過來,那在搏斗(運行時)中,老子可以隨時都能使用不同的內力,但也不能胡亂吸內力,否則你就要走火入魔了!

    3.類應該對擴展開放,對修改關閉。如果我們每個部分都用裝飾者模式進行設計,那么對于整個框架來說有點浪費,而且你也加大了代碼的難度。那什么時候使用這種模式呢?我們一般用于經常改變的地方。那我們又怎么知道哪些是經常改變的地方呢?這個就需要我們的經驗和你對所處行業的了解。建議大家平時多看點例子。

    鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

  • 發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 会理县| 卢氏县| 常德市| 墨脱县| 安平县| 佳木斯市| 京山县| 竹山县| 沐川县| 安龙县| 福建省| 凤冈县| 安平县| 射阳县| 景洪市| 蒙山县| 清新县| 江口县| 吉安市| 白山市| 搜索| 芒康县| 怀远县| 淮南市| 玛沁县| 漯河市| 罗甸县| 阳信县| 台中市| 宜春市| 汝阳县| 上饶县| 封丘县| 双鸭山市| 二连浩特市| 南宁市| 拜城县| 获嘉县| 璧山县| 东乡族自治县| 赤城县|