天天看点

大话设计模式:装饰模式

一、什么是装饰模式

给对象动态添加职责
           

装饰模式像是一场大型职责扩展会,在不同的时间你需要具备不同的职责内容,一你可以获得这些职责,二你可以放下这些职责.就增加功能来说,装饰模式比子类更灵活.是为对象已有功能添加一些其他功能的方式.客户端可以有选择的按自己的顺序装饰对象.

UML图
           
大话设计模式:装饰模式

二、适用场景

当一个对象的一些职责或功能不必一直存在,而且是能很灵活的调整的时候,就可以考虑这个装饰模式,比如那种单局获得的回到主菜单就丢失的类型,就可以在关卡里面获得的道具技能都采用装饰模式,当回到主界面就又恢复原对象 了,除了那些不必脱掉的功能.装饰这个词还是很贴切的,就像你穿衣服,你不会依赖于某件衣服,你想穿也行不穿也行.

当系统需要新功能的时候,是向旧的类中添加新代码,还是用这些新加的代码装饰原有的类.如果新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,那装饰模式就提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象.

三、优缺点

优点

装饰模式的好处就在于职责不是锁死的,能灵活调整.

对比于简单继承能避免功能繁琐的子类.把装饰功能从类中剔除,这样可以简化原有的类.

可以去除相关类中重复的装饰逻辑.

缺点

存在特定的使用条件,如果是长存的功能,使用装饰者反倒增加了类的数量.

装饰者是针对抽象组件编程Component.

种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

装扮是单一个不可重复装扮相同的对象功能,你可以重新实例一个.

四、大话中的例子

小菜装扮靓装的例子,小菜有许多种穿搭风格可选择,穿搭的顺序也是能随心替换的, 让小菜有一个抽象的装扮方法,让装饰者抽象类继承小菜,并能获得小菜进行关联,再重写装扮方法,把获得的小菜放进来.具体装扮类继承抽象装扮类,进行一些自己的特性装扮.

五、我的例子

using System;

namespace DecoratorMode
{
    class Program
    {
        static void Main(string[] args)
        {
            Naruto naruto = new Naruto("鸣人");
            Xigua xigua = new Xigua();
            Boluo boluo = new Boluo();
            Niunai niunai = new Niunai();
            Juanzhou juanzhou = new Juanzhou();
            xigua.SetCompoment(naruto);
            boluo.SetCompoment(xigua);
            niunai.SetCompoment(boluo);
            juanzhou.SetCompoment(niunai);
            juanzhou.GoShopping();
          
        }
    }

    public abstract class Compoment
    {
        public int price;
        public abstract void GoShopping();
    }

    public class Naruto : Compoment
    {
        string name;

        public Naruto(string name)
        {
            price = 30;
            this.name = name;
        }
        public override void GoShopping()
        {
            Console.WriteLine("总共花了:" + price);
            Console.WriteLine("{0}吃了拉面之后买了:", name);
        }
    }

    public class Shop : Compoment
    {
        public Compoment comp;
        public void SetCompoment(Compoment compoment)
        {
            comp = compoment;
        }
        public override void GoShopping()
        {
            if (comp != null)
            {
                comp.price += price;//这里更像是一个递归,一层一层往里找
                comp.GoShopping();
            }
        }
    }

    public class Xigua : Shop
    {
        public Xigua()
        {
            price = 15;
        }
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("西瓜");
        }
    }

    public class Boluo : Shop
    {
        public Boluo()
        {
            price = 5;
        }
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("菠萝");
        }
    }

    public class Niunai : Shop
    {
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("牛奶");
        }
    }
    public class Juanzhou : Shop
    {
        public Juanzhou()
        {
            price = 1000;
        }
        public override void GoShopping()
        {

            base.GoShopping();
            Console.WriteLine("卷轴");
        }
    }
    public class Paomian : Shop
    {
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("泡面");
        }
    }
}

           
运行结果
           
大话设计模式:装饰模式

PS: 还有些有趣的例子,比如下火锅,先有一个锅底,然后配菜都是自选的,怎么下也是随意的.还比如买奶茶,奶茶有基础款,你也可以加珍珠,加糖,等. 感觉装饰者模式实质上是一个递归的堆栈,一层套一层.每一层就是一个装饰.