装饰者模式(Decorator Pattern)

装饰者模式(Decorator Pattern)

装饰者模式(Decorator Pattern),动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

别名
包装器Wrapper
结构


参与者
Component
——定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent
——定义一个对象,可以给这个对象添加一些职责。
Decorator
——维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
ConcreteDecorator
——向组件添加职责。
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyDecorator
{
    abstract class Component
    {
        public abstract void Operation();
    }

    class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("ConcreteComponent Operation");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace MyDecorator
{
    abstract class Decorator : Component
    {
        protected Component component;


        // 对对象进行包装
//         public void SetComponent(Component component)
//         {
//             this.component = component;
//         }        


        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }


    class ConcreteDecoratorA : Decorator
    {
        private string addedState;


        public ConcreteDecoratorA(Component component)
        {
            this.component = component;
        }


        public override void Operation()
        {
            base.Operation();
            addedState = "New State";
            Console.WriteLine("ConcreteDecoratorA Operation");
        }
    }


    class ConcreteDecoratorB : Decorator
    {
        public ConcreteDecoratorB(Component component)
        {
            this.component = component;
        }


        public override void Operation()
        {
            base.Operation();
            AddeeBehavior();
            Console.WriteLine("ConcreteDecoratorB Operation");
        }


        private void AddeeBehavior()
        {


        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace MyDecorator
{
    class Program
    {
        static void Main(string[] args)
        {
//             ConcreteComponent c = new ConcreteComponent();
//             ConcreteDecoratorA da = new ConcreteDecoratorA();
//             ConcreteDecoratorB db = new ConcreteDecoratorB();
// 
//             da.SetComponent(c);
//             db.SetComponent(da);
//             db.Operation();
            ConcreteDecoratorB db = new ConcreteDecoratorB(
                new ConcreteDecoratorA(new ConcreteComponent()));
            db.Operation();


            Console.ReadKey();
        }
    }
}


效果

有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。

利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

实现

1)接口的一致性 装饰对象的接口必须与它所装饰的Component的接口是一致的。
2)省略抽象的Decorator类 当你仅需要添加一个职责时,没有必要定义抽象Decorator类。
3)保持Component类的简单性 它应集中于定义接口而不是存储数据。
4)改变对象外壳与改变对象内核(Decorator Pattern VS Strategy Pattern)

dome

装饰者模式(Decorator Pattern)_第1张图片

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

namespace MyDecorator2
{
    abstract class Beverage
    {
        public string description = "Unknown Beverage";

        public virtual string getDescription()
        {
            return description;
        }

        public abstract double cost();
    }

    class Espresso : Beverage
    {
        public Espresso()
        {
            description = "Espresso";
        }

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

    class HouseBlend : Beverage
    {
        public HouseBlend()
        {
            description = "House Blend Coffee";
        }

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

    class DarRoast : Beverage
    {
        public DarRoast()
        {
            description = "Dark Roast Coffee";
        }

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

    class Decaf : Beverage
    {
        public Decaf()
        {
            description = "Decaf";
        }

        public override double cost()
        {
            return 1.05;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyDecorator2
{
    abstract class CondimentDecorator : Beverage
    {
        public override string getDescription()
        { 
            return description;
        }
    }

    class Mocha : CondimentDecorator
    {
        Beverage beverage; // 被装饰者

        public Mocha(Beverage beverage)
        {
            this.beverage = beverage;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + ", Mocha";
        }

        public override double cost()
        {
            return beverage.cost() + 0.20;
        }
    }

    class Milk : CondimentDecorator
    {
        Beverage beverage; // 被装饰者

        public Milk(Beverage beverage)
        {
            this.beverage = beverage;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + ", Milk";
        }

        public override double cost()
        {
            return beverage.cost() + 0.10;
        }
    }

    class Soy : CondimentDecorator
    {
        Beverage beverage; // 被装饰者

        public Soy(Beverage beverage)
        {
            this.beverage = beverage;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + ", Soy";
        }

        public override double cost()
        {
            return beverage.cost() + 0.15;
        }
    }

    class Whip : CondimentDecorator
    {
        Beverage beverage; // 被装饰者

        public Whip(Beverage beverage)
        {
            this.beverage = beverage;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + ", Whip";
        }

        public override double cost()
        {
            return beverage.cost() + 0.10;
        }
    }
}
<pre name="code" class="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyDecorator2
{
    class Program
    {
        static void Main(string[] args)
        {
            Beverage beverage = new Espresso();
            Console.WriteLine(beverage.getDescription()
                + " $" + beverage.cost());

            Beverage beverage2 = new DarRoast();
            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);
            Beverage beverage3 = new Whip(new Mocha(new Soy(new HouseBlend())));
            Console.WriteLine(beverage3.getDescription()
                + " $" + beverage3.cost());

            Console.ReadKey();
        }
    }
}


 
  
 

相关模式
Adapter模式
:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。
Composite模式:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责—它的目的不在于对象聚集。
Strategy模式:用一个装饰你可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径

回顾Strategy Pattern结构


设计原则

类应该对扩展开放,对修改关闭。(遵循开放-关闭原则,通常会引入新的抽象层次,增加代码的复杂度。应该把注意力集中在设计中最有可能改变的地方,然后应用开放-关闭原则。)

java.io类使用了装饰模式。

学一门技能最好的时间是三年前。奋斗

你可能感兴趣的:(装饰者模式(Decorator Pattern))