天天看點

結合項目執行個體 回顧傳統設計模式(三)裝飾者模式

說到這個模式的項目執行個體 蟲子也滿頭疼的 所謂裝飾者模式說白了動态将職責附加到對象上。如果你在項目某個場景中需要功能擴充根據基類衍生出非常多的子類,那麼裝飾者模式無疑是很好的。不過其實在實際的項目中,往往大家不直接衍生子類,而是通過組合的方式,根據邏輯講各種擴充疊加來,對外公布的隻是一個标簽一個殼而已。

是以這個章節,蟲子就虛構一個執行個體了。還拿電商來說、點券贈品系統。

背景:

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

繼續閱讀