结合项目实例 回顾传统设计模式(三)装饰者模式

简介:

说到这个模式的项目实例 虫子也满头疼的 所谓装饰者模式说白了动态将职责附加到对象上。如果你在项目某个场景中需要功能扩展根据基类衍生出非常多的子类,那么装饰者模式无疑是很好的。不过其实在实际的项目中,往往大家不直接衍生子类,而是通过组合的方式,根据逻辑讲各种扩展叠加来,对外公布的只是一个标签一个壳而已。

所以这个章节,虫子就虚构一个实例了。还拿电商来说、点券赠品系统。

背景:

1.所有点券、优惠券、赠品券、积分继承同一个基类 基类券

2.不用种类的券可以混合搭配

3.积分根据不同的场景可以配置不同的规则

4.升级礼券在上层礼券基础上添加

一般情况下 大家可以就这样设计了

///   <summary>
    
///  基卡
    
///   </summary>
     public  abstract  class BaseCard
    {      
         public  string decription;
         public  abstract  double cost();
       
    }

     ///   <summary>
    
///  点卡A
    
///   </summary>
     public  class cardA : BaseCard
    {
         public cardA()
        {
            decription =  " cardA ";
        }
         public  override  double cost()
        {
             return  50.00;
        }
    }

     ///   <summary>
    
///  优惠券A
    
///   </summary>
     public  class couponsA : BaseCard
    {
         public couponsA()
        {
            decription =  " couponsA ";
        }
         public  override  double cost()
        {
             return  40.00;
        }
    }

     ///   <summary>
    
///  优惠券B
    
///   </summary>
     public  class couponsB : BaseCard
    {
         public couponsB()
        {
            decription =  " couponsB ";
        }
         public  override  double cost()
        {         
             return  30.00;
        }
    }

     ///   <summary>
    
///  国庆礼券
    
///   </summary>
     public  class GQCard : BaseCard
    {
        cardA a =  new cardA();
        couponsA ca =  new couponsA();
         public GQCard()
        {
            decription =  " GQCard ";
        }
         public  override  double cost()
        {
             return a.cost() + ca.cost();
        }
    }

     ///   <summary>
    
///  国庆升级A等礼券
    
///   </summary>
     public  class GQACard : BaseCard
    {
        cardA a =  new cardA();
        couponsA ca =  new couponsA();
        couponsB cb =  new couponsB();
         public GQACard()
        {
            decription =  " GQACard ";
        }
         public  override  double cost()
        {
             return a.cost() +ca.cost()+ cb.cost();
        }
    }

 

设计模式的原则是类应该对扩展开放对修改关闭,而上述设计在礼券升级种类越来越多的情况下并且现有的礼券已经频繁更新的话 对于庞大的礼券系统肯定是不理想的

那么我们换个思路

 

///   <summary>
    
///  基卡
    
///   </summary>
     public  abstract  class BaseCard
    {      
         public  string decription;
         public  abstract  double cost();
       
    }

     ///   <summary>
    
///  点卡A
    
///   </summary>
     public  class cardA : baseoupons
    {
        BaseCard basec;
         public cardA(BaseCard basec)
        {
             this.basec = basec;
            decription =  " cardA, " + basec.decription;
        }
         public  override  double cost()
        {
             return  50.00 + basec.cost(); 
        }
    }

     ///   <summary>
    
///  优惠券A
    
///   </summary>
     public  class couponsA : baseoupons
    {
        BaseCard basec;
         public couponsA(BaseCard basec)
        {
             this.basec = basec;
            decription =  " couponsA, " + basec.decription;
        }
         public  override  double cost()
        {
             return  40.00 + basec.cost();
        }
    }

     ///   <summary>
    
///  优惠券B
    
///   </summary>
     public  class couponsB : baseoupons
    {
        BaseCard basec;
         public couponsB(BaseCard basec)
        {
             this.basec = basec;
            decription =  " couponsB, " + basec.decription;
        }
         public  override  double cost()
        {
             return  30.00 + basec.cost(); 
        }
    }

     ///   <summary>
    
///  基类礼券
    
///   </summary>
     public  class baseoupons : BaseCard
    {
        BaseCard basec;
         public baseoupons(BaseCard basec)
        {
             this.basec = basec;
            decription = basec.decription;
        }
         public baseoupons()
        {
            
        }
         public  override  double cost()
        {
             if (basec !=  null)
            {
                 return basec.cost();
            }
             else
            {
                 return  0;
            }
        }
      
    }

 

 让我们看看装饰者模式的强大

 

  BaseCard a =  new baseoupons();
            a =  new cardA(a);
            a =  new couponsA(a);
            a =  new couponsB(a);

            Console.WriteLine( " 国庆礼券由 "+a.decription+ " 组成 ");
            Console.WriteLine(a.cost().ToString());

            BaseCard b =  new cardA(a);
           
            Console.WriteLine( " 国庆升级礼券由 " + b.decription +  " 组成 ");
            Console.WriteLine(b.cost().ToString());
            Console.ReadLine();

 

总结:继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式,在我们的设计当中应该允许行为可以被扩展,而无需修改现有的代码。就如上述的例子装饰者模式也可以让我们扩展行为。不过装饰者模式也有缺点,它会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。



本文转自 熬夜的虫子  51CTO博客,原文链接:http://blog.51cto.com/dubing/712406

相关文章
|
4月前
|
设计模式 Java
Java设计模式【十】:装饰者模式
Java设计模式【十】:装饰者模式
22 0
|
2月前
|
设计模式 缓存 安全
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
53 1
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——22装饰者模式
Golang设计模式——22装饰者模式
21 0
|
9月前
|
设计模式
23种设计模式_MODE08装饰者模式_手写代码实现
23种设计模式_MODE08装饰者模式_手写代码实现
|
4月前
|
设计模式 Java
根据真实业务场景去实现一下设计模式中的装饰者模式
根据真实业务场景去实现一下设计模式中的装饰者模式
18 0
|
4月前
|
设计模式 人工智能 移动开发
认真学习设计模式之装饰者模式(Decorator Pattern)
写在前言 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。通过动态地组合对象,可以写新的代码添加新功能,而无须修改现有代码。既然没有改变现有代码,那么引进bug或产生意外副作用的机会将大幅度减少。
16 0
|
7月前
|
设计模式
设计模式~~~装饰者模式
设计模式~~~装饰者模式
21 0
|
8月前
|
设计模式 Java
java实现23种设计模式-装饰者模式
java实现23种设计模式-装饰者模式
79 0
|
8月前
|
设计模式
设计模式之装饰者模式
设计模式之装饰者模式
42 0
|
9月前
|
设计模式 JavaScript 前端开发