1. 程式人生 > 其它 >設計模式專題(三)——裝飾模式

設計模式專題(三)——裝飾模式

設計模式專題(三)——裝飾模式

(原創內容,轉載請註明來源,謝謝)

一、概述

裝飾模式(Decorator)是指動態的給一個物件新增額外的職責,就增加功能來說,裝飾模式比生成子類更靈活。且裝飾模式會將需要的功能按正確的順序串聯起來控制。裝飾模式主要由幾部份組成。

1)Component抽象類,定義一個裝飾方法,繼承這個抽象類的類都需要實現裝飾方法decorate()。

2)ConcreteComponent類,繼承component,是具體裝飾方法實現的類。由該類實現將各種裝飾的方式組合起來。

3)Decorator抽象類,繼承component,其實現裝飾方法是通過傳入一個Component型別的物件,並執行其自身的decorate方法。

4)ConcreteDecorator類,繼承Decorator,起到給component新增職責的功能,即具體某一方面裝飾的功能。

二、功能

1)裝飾模式是為已有的功能動態的新增更多功能的一種方式。

2)裝飾模式把每個要要裝飾的功能放在單獨的類中,讓這個類包裝它所要裝飾的物件。當要執行特殊行為時,客戶端可以在執行時根據需要有選擇的、按順序的包裝物件。

3)把類中的功能從類中搬出,簡化原有的類。有效的把核心職責和裝飾功能分開,去除重複的裝飾邏輯。

三、場景

當要給一個類新增若干功能,這些功能之間互不相干,如果僅僅採用繼承,當需要載入十幾個功能,就需要十幾重的繼承,這樣程式碼沒法維護。當需要修改一個內容,會影響到非常多的類。

此時,就需要用到裝飾者模式,讓這些新增的內容類都繼承同一個父類,而這個父類又和原先待新增的類共同繼承一個類,這樣便於互相之間的呼叫。

四、UML類圖如下

五、實現

1、設計場景

現設計資料處理類,有一個字串和一個數組,字串和陣列分別需要經過選擇一種方式格式轉換、選擇一種方式加密。

因此,需要定義如下幾個類:

1)資料處理抽象類(DataDealer類形如上圖的component類)

2)資料處理實現類(DataDealerConcrete類形如上圖的concretecomponent類)

3)資料處理裝飾類(DataDecorator類形如上圖的decorator類)

4)資料處理具體裝飾類(TypeExchange、TransType類形如上圖concretedecoratorA、B類)

2、PHP實現如下

<?php
//實現裝飾模式,場景:資料處理
/*
 現設計資料處理類,有一個字串和一個數組,
 字串和陣列分別需要經過選擇一種方式格式轉換、選擇一種方式加密
 因此,需要定義如下幾個類:
         1)資料處理抽象類(DataDealer類)
         2)資料處理實現類(DataDealerConcrete類)
         3)資料處理裝飾類(DataDecorator類)
         4)資料處理具體裝飾類(TypeExchange、TransType類)
*/
//資料處理抽象類
abstract class DataDealer{
         private $method;//資料處理方法
         public functiondeal(){}
}
//資料處理裝飾類
abstract class DataDecorator extends DataDealer{
         private$dealIns;//datadealer的例項
         private $method;//資料處理方法
         public function__construct(DataDealer $dealIns, $method){
                   $this->dealIns= $dealIns;
                   $this->method= $method;
         }
         public functiondeal(){
                   $data =$this->dealIns->deal();
         }       
}
//資料處理具體類A——格式轉換
class TypeExchange extends DataDecorator{
         private$dealIns;//datadealer的例項
         private $method;//資料處理方法
         public function__construct(DataDealer $dealIns, $method){
                   $this->dealIns= $dealIns;
                   $this->method= $method;
         }
         public functiondeal(){
                   $data =    $this->dealIns->deal();
                   switch($this->method){
                            case'array2string'://陣列轉字串
                                     $data= $this->array2string($data);
                                     break;
                            case'string2array'://字串轉陣列
                                     $data= $this->string2array($data);
                                     break;
                            default:
                                     break;
                   }
                   return$data;
         }       
         private functionstring2array($data){}
         private functionarray2string($data){
                   if(!is_array($data)){
                            return$data;
                   }
                   $str = '';
                   foreach($dataas $item){
                            if(is_array($item)){
                                     $str.= $this->array2string($data);
                            }else{
                                     $str.= $item . '|';
                            }
                   }
                   return $str;
         }
}
//資料處理具體類B——序列化方式用於傳輸
class TransType extends DataDecorator{
         private$dealIns;//datadealer的例項
         private $method;//資料處理方法
         public function__construct(DataDealer $dealIns, $method){
                   $this->dealIns= $dealIns;
                   $this->method= $method;
         }
         public functiondeal(){
                   $data =    $this->dealIns->deal();             
                   switch($this->method){
                            case'enjson'://json
                                     $data= $this->enJson($data);
                                     break;
                            case'enseria'://serialize
                                     $data= $this->enSeria($data);
                                     break;
                            default:
                                     break;
                   }
                   return$data;
         }
         private functionenJson($data){
                   returnjson_encode($data);
         }
         private functionenSeria($data){
                   returnserialize($data);
         }
}
//資料處理實現類
class DataDealerConcrete extends DataDealer{
         private $data;
         public function__construct($data){
                   $this->data= $data;
         }
         public functiondeal(){
                   return$this->data;
         }
}
//客戶端,呼叫上述功能實現資料處理
$dataDealerString = new DataDealerConcrete('abcdefg');
$typeExchangeString = new TypeExchange($dataDealerString, 'none');
$transTypeString = new TransType($typeExchangeString, 'enjson');
var_dump($transTypeString->deal('abcdefg'));
$dataDealerArray = new DataDealerConcrete(array('a', 'b', 'c','d'));
$typeExchangeArray = new TypeExchange($dataDealerArray,'array2string');
$transTypeArray = new TransType($typeExchangeArray, 'enseria');
var_dump($transTypeArray->deal(array('a', 'b', 'c', 'd')));

——written by linhxx 217.07.28

相關閱讀:

設計模式專題(二)——策略模式

設計模式專題(一)——面向物件的設計原則