设计模式理解:装饰模式Decorator

装饰模式,又称包装器(wrapper),该模式的使用场景是,动态的给对象扩展一些额外的职责。职责即功能,所谓“动态”表示可以任意搭配我想要的功能,功能调用的先后顺序也可以任意设置。

用组合的方式来代替继承的方式,避免子类膨胀和继承的滥用,使“对象功能扩展”能够根据需要来动态的扩展实现。例如在抽象类Stream中,派生了 文件流,网络流,内存流,等如果要在着三个流上添加流的加密,流的缓存,流的加密和缓存功能,可以比较方法1继承的实现方式和方法2组合的形式。

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()
 }
};

第一种方法实际上就是滥用继承的例子:假如现有一个需求“需要给文件流网络流新增一个缓存的功能”,按照第一种的设计方式是不是要在派生出 ”缓存文件流类“,”缓存网络流类“呢?假如需要再新增一个网络流,按照第一种方法是不是要新增一个继承Stream 的网络流类,再派生出 “加密网络流类”,"缓存网络流类" 呢? 实际上,第一种的设计存在很大的代码冗余,文件流,内存流,网络流等实体类在加密时的过是一样的,即“稳定”,唯一变化的实际上是读查写操作。文件流和加密文件流之间的关系实际上并不应是“父子关系”,继承的正确使用场景应是业务理论上面的细化,例如平行四边形和矩形的关系,矩形和正方形的关系,而功能上的扩展不应该用继承,而应该用组合,例如“正方形 与 涂上颜色的正方形之间的关系”就不该用继承。

装饰模式实际上就是组合

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 () ; //先缓存后加密写文件
}

上述就是装饰模式,如果 DecoratorStream 类没有继承Stream ,那么就不支持先缓存后加密写文件的功能,继承了Stream就表示装配了该功能后还是个stream对象。DecoratorStream类中没有Stream * stream; 成员指针,那么就没法进行功能上的装饰,和方法1比起来,大大简化了代码,摆脱了继承的滥用。增强了可维护性,将来如果“细化5个流的实体类和5个流的功能”方法1需要新增的类的数量就是巨大的,而方法而只需要新增10个就可在实现流功能的任意搭配。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值