模式三:装饰者模式

牢记:代码应该如同晚霞中的莲花一样地关闭(免于改变),如同晨曦中的莲花一样地开放(能够扩展)。

3.1装饰者模式定义:

  动态地将动作附加到对象上,动作可以根据需要任意叠加(装饰)。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

 

3.2装饰者模式UML类图:

 

      Component是被装饰者和装饰者之间所共同拥有的行为,可以抽象类或接口的方式实现,有别于以传统的以抽象类实现的方式,本文中以接口的方式来实现。Decorator为装饰者共同拥有的行为,同样以接口的方式实现。

 

 

3.3应用场景

装饰在生活中的理解,即是某种东西被几种不同的东西来修饰。例如生日蛋糕上可能有蜡烛,也可能有文字,也可能有水果,蜡烛、文字、水果都是用来装饰蛋糕的。当我们计算蛋糕的价格时,所有的装饰者和蛋糕(被装饰者)都有一个共同的动作,即各自计算自己的价格,然后全部相加,即得出整个蛋糕的价格。实际上,当一个对象和N个其它对象之间都有共同的动作(接口相同),而且有需求将这N个对象(装饰者)任意的动态的将动作叠加在一个对象(被装饰者)上,那么,我们就可以利用装饰者模式。

                                                                                      

3.4装饰者模式分析与实现(c#描述)                 

 

//装饰者和被装饰者共同实现的接口

    public interface IBehavior

    {       

        string GetDescription();

        int Cost();

    }

 

    //装饰者实现的接口

    public interface IDecorator : IBehavior

    {       

        void ReportMyQulity();//报告装饰者的质量

    }

 

    //被装饰者:蛋糕

    public class Cake : IBehavior

    {

        public string GetDescription()

        {

            return "I'm a Cake.";

        }

 

        public int Cost()

        {

            return 2;

        }

    }   

 

 

    //装饰者:蜡烛

    public class Candle : IDecorator

    {

        private IBehavior iBehavior;

 

        public Candle(IBehavior ai_Behavior)

        {

            this.iBehavior = ai_Behavior;

        }

 

        public string GetDescription()

        {

            return iBehavior.GetDescription() + " Decorated by Lazhu. ";

        }

 

        public int Cost()

        {

            return iBehavior.Cost() + 3;

        }

 

        public void ReportMyQulity()

        {

            Console.WriteLine("我质量很好的!");

        }

            

    }

 

    //装饰者:文字

    public class Text : IDecorator

    {

        private IBehavior iBehavior;

 

        public Text(IBehavior ai_Behavior)

        {

            this.iBehavior = ai_Behavior;

        }

 

        public string GetDescription()

        {

            return this.iBehavior.GetDescription() + " Decorated by Text. ";

        }

 

        public int Cost()

        {

            return this.iBehavior.Cost() + 3;

        }

 

        public void ReportMyQulity()

        {

            Console.WriteLine("我质量一般!");

        }

    }

 

    //装饰者:水果

    public class Fruit : IDecorator

    {

        private IBehavior iBehavior;

 

        public Fruit(IBehavior ai_Behavior)

        {

            this.iBehavior = ai_Behavior;

        }

 

        public string GetDescription()

        {

            return this.iBehavior.GetDescription() + " Decorated by Fruit. ";

        }

 

        public int Cost()

        {

            return this.iBehavior.Cost() + 5;

        }

 

        public void ReportMyQulity()

        {

            Console.WriteLine("我质量不好哦!");

        }

    }

 

    //调用类

    public class Decorator_Test

    {

        public static void Do()

        {

            IBehavior Cake = new Cake();//建一个被装饰者

 

            Cake = new Candle(Cake);//用蜡烛来装饰

            Cake = new Text(Cake);//用文字来装饰

            Cake = new Fruit(Cake);//用水果来装饰

 

            Console.WriteLine(Cake.GetDescription()+" 我的成本是:"+Cake.Cost()+"元。");

        }

  }

 

至此,装饰者模式完毕。

装饰者模式体现了上述的面向对象设计的几个原则,下面重点强调一下其中之一:类应该对扩展开放,对修改关闭

很明显,在装饰者模式中,如果我们要扩展一个类的行为,则只需为其添加不同的装饰者,而不需要修改被装饰者的任何代码,一个蛋糕可以用水果来装饰,也可以用文字来装饰,也可以用蜡烛装饰2次,也可以完全不装饰,这些都取决于客户的实际需要。我们可以用无数个装饰者包装一个对象,但装饰者模式的缺点是:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变得复杂。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值