第三章 裝飾者模式

裝飾者模式

參考《head first 設計模式》
裝飾者模式像包了一層層糖紙的糖果,每一層糖紙都繼承自同一個基類。遵循開閉設計原則,即對擴展開放,對修改關閉。就是寫好的代碼能不改就不要改,改了可能要加班加點了。這個模式像那種二道販子,把別人做好的東西做個包裝,添加點自己的東西再拿出去賣。
定義:動態的將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更富有彈性的替代方案。
特徵:

  1. 裝飾者和被裝飾者具有相同的基類;
  2. 可以用一個或多個裝飾者包裝一個對象;
  3. 既然裝飾者和被裝飾者具有相同的基類,可以用裝飾者替代被裝飾者;
  4. 裝飾者可以在被裝飾者的行爲前或後,添加自己的行爲;
  5. 對象可以在任何時候被裝飾。

心得

裝飾者和被裝飾者必須要繼承自同一個基類的目的是,在裝飾者的內部有基類型字段用來保存被裝飾者,一個裝飾者被再次裝飾後,它對於後者而言就成了被裝飾者,如果不是繼承自同一個基類,它就不能保存到後者的基類型字段裏了,從而無法再次被擴展。

## 結構
這裏寫圖片描述

## 示例代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 裝飾者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Beverage beverage=new Espresso(); // 一杯濃咖啡,不加調料
            Console.WriteLine($"{beverage.GetDescription()} ${beverage.Cost()}");

            Beverage beverage2=new DarkRoast(); // 一杯深焙咖啡
            beverage2=new Mocha(beverage2); // 添加摩卡
            beverage2 = new Mocha(beverage2); // 添加摩卡
            beverage2 = new Whip(beverage2); // 添加奶泡
            Console.WriteLine($"{beverage2.GetDescription()} ${beverage2.Cost()}");

            Beverage beverage3=new HouseBlend(); // 一杯混合咖啡
            beverage3=new Soy(beverage3); // 添加豆漿
            beverage3=new Mocha(beverage3); // 添加摩卡
            beverage3=new Whip(beverage3); // 添加奶泡
            Console.WriteLine($"{beverage3.GetDescription()} ${beverage3.Cost()}");

            Console.ReadKey();
        }
    }


    #region 計算咖啡飲料的價格

   // 咖啡飲料中可能加入不同的飲料,價格也可能會發生改變

    // 飲料抽象類,一般裝飾者模式用抽象類,也可以用接口
    public abstract class Beverage
    {
       public string Description = "Unknown Beverage";

        public virtual string GetDescription()
        {
            return Description;
        }

        // 計算飲料價格
        public abstract double Cost();
    }

    // 調料裝飾者抽象類,給所有具體的調料類繼承
    public abstract class CondimentDecorator : Beverage
    {
        // 覆蓋基類中的獲取描述的方法
        public override string GetDescription()
        {
            return string.Empty;
        }
    }

    #region 被裝飾者組件

    // 特濃咖啡類
    public class Espresso : Beverage
    {
        public Espresso()
        {
            Description = "Espresso";
        }

        public override double Cost()
        {
            return 1.99;
        }
    }

    // 混合咖啡類
    public class HouseBlend : Beverage
    {
        public HouseBlend()
        {
            Description = "HouseBlend";
        }

        public override double Cost()
        {
            return 0.89;
        }
    }

    // 深焙咖啡類
    public class DarkRoast : Beverage
    {
        public DarkRoast()
        {
            Description = "DarkRoast";
        }

        public override double Cost()
        {
            return 0.99;
        }
    }

    // 低咖啡因咖啡類
    public class Decaf : Beverage
    {
        public Decaf()
        {
            Description = "Decaf";
        }

        public override double Cost()
        {
            return 1.05;
        }
    }

    #endregion

    #region 裝飾者

    // 各種咖啡配料

    // 摩卡
    public class Mocha : CondimentDecorator
    {
        private readonly Beverage _beverage; // 保存被裝飾者

        public Mocha(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override string GetDescription()
        {
            return _beverage.GetDescription() + ", Mocha";
        }

        public override double Cost()
        {
            return .20 + _beverage.Cost();
        }
    }

    // 牛奶
    public class Milk : CondimentDecorator
    {
        private readonly Beverage _beverage; // 保存被裝飾者

        public Milk(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override string GetDescription()
        {
            return _beverage.GetDescription() + ", Milk";
        }

        public override double Cost()
        {
            return .10 + _beverage.Cost();
        }
    }

    // 豆漿
    public class Soy : CondimentDecorator
    {
        private readonly Beverage _beverage; // 保存被裝飾者

        public Soy(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override string GetDescription()
        {
            return _beverage.GetDescription() + ", Soy";
        }

        public override double Cost()
        {
            return .15 + _beverage.Cost();
        }
    }

    // 奶泡
    public class Whip : CondimentDecorator
    {
        private readonly Beverage _beverage; // 保存被裝飾者

        public Whip(Beverage beverage)
        {
            _beverage = beverage;
        }

        public override string GetDescription()
        {
            return _beverage.GetDescription() + ", Whip";
        }

        public override double Cost()
        {
            return .10 + _beverage.Cost();
        }
    }

    #endregion

    #endregion


}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章