Design pattern understanding: decorative pattern Decorator

Decoration mode, also known as wrapper (wrapper), the usage scenario of this mode is to dynamically extend some additional responsibilities to the object. Responsibilities are functions. The so-called "dynamic" means that I can arbitrarily match the functions I want, and the order of function calls can also be set arbitrarily.

Use combination to replace inheritance, to avoid subclass expansion and abuse of inheritance, so that "object function extension" can be dynamically extended as needed. For example, in the abstract class Stream, file stream, network stream, memory stream, etc. are derived. If you want to add stream encryption, stream cache, stream encryption and cache functions to the three streams, you can compare the implementation inherited by method 1. Method and method 2 combined form.

class Stream{
public:
 virtual char read(int num) = 0;
 virtual void seek(int num) = 0;
 virtual void write(int num) = 0;
};
//文件流
class FileStream:Stream{
public :
 virtual char read(int num) {
  // 读文件的功能
     //fileread();
 }
 virtual void seek(int num){
  // 查询文件功能
    //fileseek();
 }
 virtual void write(int num) {
    //写文件功能 
    //fileWrite()
 }
};
 
//内存流
class MemoryStream:Stream{
public :
 virtual char read(int num) {
  // 读内存的功能
     //memoryread();
 }
 virtual void seek(int num){
  // 查询内存功能
    //memoryseek();
 }
 virtual void write(int num) {
    //写内存功能 
    //memoryWrite()
 }
};
//加密文件流类
class CryptoFileStream : public FileStream{
     virtual char read(int num) {
  // 加密内容
  // crypto();
  // 读文件的功能
     //fileread();
 }
 virtual void seek(int num){
    // 加密内容
    // crypto();
    // 查询文件功能
    //fileseek();
    // 解密内容
    // decrypto();
 }
 virtual void write(int num) {
    // 加密内容
    // crypto();
    //写文件功能 
    //fileWrite()

 }
};
//加密内存流
class CryptoMemoryStream: public:MemoryStream{
public :
 virtual char read(int num) {
 // 加密内容
  // crypto();
  // 读内存的功能
     //memoryread();
 }
 virtual void seek(int num){
 // 加密内容
  // crypto();
  // 查询内存功能
    //memoryseek();
  // 解密内容
    // decrypto();
 }
 virtual void write(int num) {
  // 加密内容
    // crypto();
    //写内存功能 
    //memoryWrite()
 }
};

The first method is actually an example of abusing inheritance: if there is an existing requirement "need to add a cache function to the file stream network stream", according to the first design method, is it necessary to derive the "cache file stream class" "," What about "Cached Network Streaming"? If you need to add another network stream, do you need to add a new network stream class that inherits Stream according to the first method, and then derive "encrypted network stream class" and "cached network stream class"? In fact, the first design has a lot of code redundancy. The file stream, memory stream, network stream and other entities have the same experience during encryption, that is, "stable". The only change is actually reading, checking and writing. operating. The relationship between the stream and the stream files should be encrypted files do not actually "parent-child relationship" inherit proper use business scenarios should be refined above theory , such as the relationship of the rectangular parallelogram, rectangular and square relationship, and Functional expansion should not use inheritance, but should use combination . For example, "the relationship between a square and a colored square" should not use inheritance.

The decoration mode is actually a combination

class Stream{
public:
 virtual char read(int num) = 0;
 virtual void seek(int num) = 0;
 virtual void write(int num) = 0;
};
//文件流
class FileStream:Stream{
public :
 virtual char read(int num) {
  // 读文件的功能
     //fileread();
 }
 virtual void seek(int num){
  // 查询文件功能
    //fileseek();
 }
 virtual void write(int num) {
    //写文件功能 
    //fileWrite()
 }
};
 
//内存流
class MemoryStream:Stream{
public :
 virtual char read(int num) {
  // 读内存的功能
     //memoryread();
 }
 virtual void seek(int num){
  // 查询内存功能
    //memoryseek();
 }
 virtual void write(int num) {
    //写内存功能 
    //memoryWrite()
 }
};
//功能装饰流类
class DecoratorStream : public Stream{
  protected:
  Stream * stream;
  public:
  DecoratorStream(Stream * s ):stream(s){}
};
//流加密
class CryptoStream: public DecoratorStream {
public :
 CryptoStream( Stream *s):DecoratorStream (s){}
 virtual char read(int num) {
  // 加密内容
  // crypto();
  stream ->read();
 }
 virtual void seek(int num){
 // 加密内容
  // crypto();
  // 查询
  stream ->seek();
  // 解密内容
    // decrypto();
 }
 virtual void write(int num) {
    // 加密内容
    // crypto();
    //写功能 
    stream ->Write()
 }
};
//流缓存
class BufferStream: public DecoratorStream {
public :
 BufferStream( Stream *s):DecoratorStream (s){}
 virtual char read(int num) {
   //读缓存
   if(bufferread() == null){
   
   stream ->read();
   //写缓存内容
   bufferwrite();    
   }
 }
 virtual void seek(int num){
   //读缓存
   if(bufferread() == null){
   
   stream ->seek();
   //写缓存内容
   bufferwrite();    
   }
 }
 virtual void write(int num) {
    //写功能 
    stream ->Write()
    bufferwrite();  
 }
};
///
void main(){
    Stream* fstream = new FileStream();
    fstream->write() ; //写文件
    Stream * cryptofstream = new  CryptoStream(fstream) ;
    cryptofstream  ->write() ; // 加密写文件
    Stream * buffercryptofstream = new  BufferStream(cryptofstream) ;
    buffercryptofstream ->write () ; //先缓存后加密写文件
}

The above is the decoration mode. If the DecoratorStream class does not inherit Stream, it does not support the function of caching and then encrypting and writing files. Inheriting Stream means that it is still a stream object after the function is assembled. There is no Stream * stream; member pointer in the DecoratorStream class, so functional decoration is impossible. Compared with method 1, the code is greatly simplified and the abuse of inheritance is eliminated. The maintainability is enhanced. In the future, if "refine the entity classes of 5 streams and the functions of 5 streams" method 1, the number of new classes that need to be added is huge, and the method only needs to add 10 new classes to achieve Any combination of streaming functions.

 

 

 

Guess you like

Origin blog.csdn.net/superSmart_Dong/article/details/114242180