结构型模式之装饰模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构型模式之装饰模式相关的知识,希望对你有一定的参考价值。

概述

装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为,在现实生活中,这种情况也到处存在,例如一张照片,我们可以不改变照片本身,给它增加一个相框,使得它具有防潮的功能,而且用户可以根据需要给它增加不同类型的相框,甚至可以在一个小相框的外面再套一个大相框。

装饰模式是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能。

定义

装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。

实现

家电类

    /// <summary>
    /// 家电类
    /// </summary>
    public abstract class Appliance
    {
        /// <summary>
        /// 显示功能方法
        /// </summary>
        public abstract void Display();
    }

具体家电类-电饭煲类

    /// <summary>
    /// 电饭锅类
    /// </summary>
    public class ElectricCooker : Appliance
    {
        /// <summary>
        /// 电饭锅功能:煮饭
        /// </summary>
        public override void Display()
        {
            Console.WriteLine("煮饭");
        }
    }

家电装饰类

    /// <summary>
    /// 家电装饰类
    /// </summary>
    public abstract class ApplianceDecorater : Appliance
    {
        private Appliance appliance;
        public ApplianceDecorater(Appliance appliance)
        {
            this.appliance = appliance;
        }
        public override void Display()
        {
            if (appliance != null)
                appliance.Display();
        }
    }

煮粥装饰类

    /// <summary>
    /// 煲汤装饰类
    /// </summary>
    public class CookCongeeDecorater : ApplianceDecorater
    {
        public CookCongeeDecorater(Appliance appliance) : base(appliance)
        {
        }
        public override void Display()
        {
            //扩展煲汤功能
            CookCongee();
            base.Display();
        }

        private void CookCongee()
        {
            Console.WriteLine("煮粥");
        }
    }

煲汤装饰类

    /// <summary>
    /// 煲汤装饰类
    /// </summary>
    public class CookSoupDecorater : ApplianceDecorater
    {
        public CookSoupDecorater(Appliance appliance) : base(appliance)
        {
        }
        public override void Display()
        {
            //扩展煲汤功能
            CookSoup();
            base.Display();
        }

        private void CookSoup()
        {
            Console.WriteLine("煲汤");
        }
    }

客户端

        static void Main(string[] args)
        {
            //实例化一个电饭煲类-能煮饭
            Appliance electricCooker = new ElectricCooker();
            //装饰电饭煲-扩展煲汤功能
            ApplianceDecorater cookSoup = new CookSoupDecorater(electricCooker);
            //在装饰后的电饭煲上继续扩展-增加煮粥功能
            ApplianceDecorater cookCongee = new CookCongeeDecorater(cookSoup);
            //显示目前电饭煲具有的功能
            cookCongee.Display();
            Console.ReadLine();
        }

总结

主要优点

1、 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加。

2、 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,得到功能更为强大的对象。

3、 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。

主要缺点

1、使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用更多的系统资源,在一定程序上影响程序的性能。

2、装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。

以上是关于结构型模式之装饰模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之装饰者模式

设计模式之装饰模式20170726

JAVA SCRIPT设计模式--结构型--设计模式之Decorator装饰模式

结构型模式之装饰模式

C++之装饰(decorator)模式

OOAD-设计模式结构型模式之适配器装饰器代理模式