天天看点

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

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

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

背景:

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

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

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

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

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

/// <summary>

    /// 基卡

    /// </summary>

    public abstract class BaseCard

    {      

        public string decription;

        public abstract double cost();

    }

    /// <summary>

    /// 点卡A

    public class cardA : BaseCard

    {

        public cardA()

        {

            decription = "cardA";

        }

        public override double cost()

            return 50.00;

    /// 优惠券A

    public class couponsA : BaseCard

        public couponsA()

            decription = "couponsA";

            return 40.00;

    /// 优惠券B

    public class couponsB : BaseCard

        public couponsB()

            decription = "couponsB";

        {         

            return 30.00;

    /// 国庆礼券

    public class GQCard : BaseCard

        cardA a = new cardA();

        couponsA ca = new couponsA();

        public GQCard()

            decription = "GQCard";

            return a.cost() + ca.cost();

    /// 国庆升级A等礼券

    public class GQACard : BaseCard

        couponsB cb = new couponsB();

        public GQACard()

            decription = "GQACard";

            return a.cost() +ca.cost()+ cb.cost();

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

那么我们换个思路

    public class cardA : baseoupons

        BaseCard basec;

        public cardA(BaseCard basec)

            this.basec = basec;

            decription = "cardA," + basec.decription;

            return 50.00 + basec.cost(); 

    public class couponsA : baseoupons

        public couponsA(BaseCard basec)

            decription = "couponsA," + basec.decription;

            return 40.00 + basec.cost();

    public class couponsB : baseoupons

        public couponsB(BaseCard basec)

            decription = "couponsB," + basec.decription;

            return 30.00 + basec.cost(); 

    /// 基类礼券

    public class baseoupons : BaseCard

        public baseoupons(BaseCard basec)

            decription = basec.decription;

        public baseoupons()

            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

继续阅读