設計模式 裝飾者模式

2022-05-12 22:00:04 字數 3472 閱讀 9628

考慮程式要對一類(網路流,io流等等)進行操作。進行什麼操作呢?可能在讀(read)這個流的時候對這個流進行加密,也可能對這個流進行快取。

那麼很自然的能設計出以下這些類

class

stream ;

class iostream : public stream {};   //

輸入輸出流

class netstream: public stream {}; //

網路流class bufferediostream : public

iostream

void

buffer() {}              

};       

class encryptiostream : public

iostream

void

encrypt();                     }//

實現加密和快取功能的輸入輸出流

class bufferedencryptiostream : public

encryptiostream,

public

bufferediostream

};//

網路流同理

class bufferednetstream : public netstream ......

那麼這樣做的缺點有什麼呢?試想一下,如果我現在要對流增加新的操作,比如說要將流輸出。你可能會有如下設計

class printiostream : public

iostream

void

print();

}class bufferedprintiostream : public

bufferediostream,

public

printiostream

};  

class encryptprintiostream : public

encryptiostream,

public printiostream {};  //

既可以加密有可以列印的io流

class bufferedencryptprintiostream : public

bufferedprintiostream,

public encryptprintiostream {};

哇靠,有沒有搞錯!只不過是要求增加了乙個新的列印的功能,結果多出了這麼多的類。如果繼續增加新功能的話,類的數量之多可想而知。這種現象被稱作類**

當然了,你也可以說只設計乙個bufferedencryptprintiostream。但是假如你某個時刻不需要列印功能的話,那麼列印功能就是累贅,這顯然違背了介面隔離原則

這時候就需要一種更好的設計方法----裝飾者模式

試想一下,如果我們通過組合的方式來設計類會不會有上述問題呢?答案是不會。

//

裝飾者模式一瞥

class bufferedstream : public

stream

void read()

void buffer();

private

:  stream*mystream;

};

嗯?這個類怎麼這麼奇怪,又是繼承了stream,裡面又包含了乙個stream。這其實就是裝飾者模式的精髓。之所以繼承是因為bufferedstream首先是個流,它可能有一些stream通用的性質。而為什麼它的成員函式也包含個stream物件?請注意,這裡的stream是乙個指標,對c++敏感的朋友可能已經意識到了指標意味著可以動態繫結。那麼我們看看如何使用這個bufferedstream以實現上述的各種功能

//

如果我們想要乙個緩衝的io流

iostream* stm = new

iostream();

bufferedstream* bufferedstm = new

bufferedstream(stm);

bufferedstm->read();

//如果我們要乙個緩衝的加密的io流

encryptstream* encryptstream = new encryptstram(new

iostream);

bufferedstream* bufencstream = new

bufferedstream(encryptstream);

bufencstream->read();

是不是覺得很神奇?關鍵點在於對流的層層包裝,比如說先把流包裝成可列印的流,那麼它就能實現列印的功能了。在這個基礎上把它包裝成快取流,那麼它既有快取功能有有列印功能。如果需要更多的功能怎麼辦?繼續包裝就是了。這樣子就無需為新的功能拓展類,從而避免了類**的問題

以上就是裝飾者模式,接下來給出裝飾者模式的完整設計**

class

stream ;

class iostream : public

stream {};

class

printstream : stream

void

read()

void

print() {}

private

:  stream*mystream;

};class

bufferedstream : stream

void

read()   

void

buffer();

private

:  stream*mystream;

};class

encryptstream : stream

void

read()

void

encrypt();

private

:  stream*mystream;}//

只需這幾個類就能完成所有需要的功能,接下來看看使用方法

iostream* iostm = new

iostream();

bufferedstream* bufferedprintencryptstream =

new bufferedstream(new printstream(new encryptstream(iostm)));

更近一步。細心的朋友可能已經發現了三個類中都有乙個mystream成員,那麼能優化的是將mystream放在乙個新的類中,然後讓這三個類繼承這個新的類

class mystream : stream 

private:

stream* mystream;

}

以上就是裝飾者模式的所有內容

設計模式 裝飾者模式

public abstract class beverage public abstract double cost public abstract class condimentdecorator extends beverage public class darkroast extends be...

設計模式 裝飾者模式

沒什麼特別的,之前看懂了,這次自己再複述一下。畢竟把別人講懂了才是真的懂了。主要參考了head first 設計模式。例子講述的是在為星巴克咖啡的製作訂單的情況,比如客人點了飲料,那麼系統會自動算出 不知道是我沒有體會到,還是這個例子不太合適,算出 那麼簡單的事還需要用到類?不過不影響我們思考裝飾者...

設計模式 裝飾者模式

好幾天沒出部落格了,在學習android的一些新控制項的時候,用到了乙個模式,叫裝飾者模式,所以在此講講這個模式。模式,包含以下四個角色 1 抽象構件 component 角色 給出乙個抽象介面,以規範準備接收附加責任的物件。2 具體構件 concretecomponent 角色 定義乙個將要接收附...