大話設計模式讀書筆記5——裝飾模式

Rising_Sun發表於2014-11-16

裝飾模式(Decorator):動態地給一個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。

裝飾模式結構圖:

裝飾模式實現程式碼:

    /// <summary>
    /// 宣告一個Component的抽象基類
    /// </summary>
    abstract class Component
    {
        public abstract void Operation();
    }

    /// <summary>
    ///宣告一個具體的Component,繼承Component
    /// </summary>
    class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("ConcreteComponent.Operation()");
        }
    }

    /// <summary>
    /// 宣告一個抽象的裝飾類'Decorator'
    /// 並繼承Component
    /// </summary>
    abstract class Decorator : Component
    {
        protected Component component;

        //裝飾方法
        public void SetComponent(Component component)
        {
            this.component = component;
        }

        //重寫 Operation 方法
        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    /// <summary>
    /// 宣告一個具體裝飾類A,繼承Decorator
    /// </summary>
    class ConcreteDecoratorA : Decorator
    {
        public override void Operation()
        {
            //一些功能擴充套件
            Console.WriteLine("ConcreteDecoratorA.Operation()");
            base.Operation();            
        }
    }

    /// <summary>
    /// 宣告一個具體裝飾類B,繼承Decorator
    /// </summary>
    class ConcreteDecoratorB : Decorator
    {
        public override void Operation()
        {
           //一些功能擴充套件
            AddedBehavior();
            Console.WriteLine("ConcreteDecoratorB.Operation()");
            base.Operation();
        }

        //裝飾類B自有方法
        void AddedBehavior()
        {
        }
    }

 class Program
    {
        static void Main(string[] args)
        {  
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();
           
            d1.SetComponent(c);
            d2.SetComponent(d1);
            d2.Operation();
           
            Console.ReadKey();
        }
    }

  執行結果:

 我們可以通過一個簡單是例項,還應用一下裝飾模式,比如現在有一種坦克,坦克有很多的型號和特色,有的具有紅外功能,有的具有GPS定位功能,通過使用裝飾模式,大大降低了子類的膨脹。

 //坦克基類
    public class Tank
    {
        /// <summary>
        /// 射擊
        /// </summary>
        public virtual void Shoot()
        {

        }

    }

    //T50 型坦克
    public class T50Tank:Tank
    {
        public override void Shoot()
        {
            Console.WriteLine("T50 型號坦克射擊");
        }
    }

    //T51型坦克
    public class T51Tank : Tank
    {
        public override void Shoot()
        {
            Console.WriteLine("T51 型號坦克射擊");
        }
    }

    //裝飾基類
    public abstract class Decorator : Tank
    {
        protected Tank tank;

        //利用構造器進行裝飾
        public Decorator(Tank tank)
        {
            this.tank = tank;
        }          

        public override void Shoot()
        {
            if (tank != null)
            {
                tank.Shoot();
            }
        }
    }

    //具有紅外功能
    public class InfraRed : Decorator
    {
        public InfraRed(Tank tank)
            : base(tank)
        {

        }
    
        public override void Shoot()
        {
            Console.WriteLine("帶紅外功能");
            base.Shoot();
        }
    }

    //具有GPS功能
    public class GPS : Decorator
    {
        public GPS(Tank tank)
            : base(tank)
        {

        }
        public override void Shoot()
        {
            Console.WriteLine("帶GPS功能");
            base.Shoot();
        }
    }

 class Program
    {
        static void Main(string[] args)
        {
            //宣告一個T50型坦克
            Tank t50Tank = new T50Tank();
            //給T50型坦克賦予紅外功能
            InfraRed red = new InfraRed(t50Tank);
            //給T50型坦克賦予GPS功能
            GPS gps = new GPS(red);
            gps.Shoot();          

            Console.ReadKey();
        }
    }

 執行結果:

相關文章