分享

C#设计模式系列:装饰模式(Decorator)

 雪柳花明 2016-09-13

1. 装饰模式简介

  装饰模式动态地给一个对象添加额外的职责。例如一幅画有没有画框都可以挂在墙上,画就是被装饰者。但是通常都是有画框的。在挂在墙上之前,画可以被蒙上玻璃,装到框子里,所以在画上加一层画框,并把它们组合成一个整体——有框的画。这样随着不断有新的装饰的加入,就给商品不断地打上包装,变成一个功能更让人满意的商品。这种不断打包装的过程就是装饰。

1.1 定义

  装饰模式提供了一种给类增加功能的方法。它通过动态地组合对象,可以给原有的类添加新的代码,而无须修改现有代码。因此引入bug或产生意外副作用的机会将大幅度减少。

1.2 使用频率

   中等

2. 装饰模式结构图

2.1 结构图

2.2 参与者

  装饰模式参与者:

   Component:定义一个对象接口,可以给这些对象动态地添加职责

   ConcreteComponent:定义一个对象,可以给这个对象添加一些职责

   Decorator:维持一个指向Component的指针,并定义一个与Component接口一致的接口

   ConcreteDecorator:负责向ConcreteComponent添加功能

  在装饰模式中,Decorator定义了一个装饰接口类。因为Decorator与ConcreteComponent继承同一个接口,所以继承Decorator的类ConcreteDecorator可以使用ConcreteComponent的方法,再在ConcreteDecorator里面加入一些新的方法,也就是装饰,就成为了一个包装好的装饰类。

3、装饰模式结构实现

  

  Component.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.DecoratorPattern.Structural
{
    public abstract class Component
    {
        public abstract void Operation();
    }
}
复制代码

  ConcreteComponent.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.DecoratorPattern.Structural
{
    public class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("ConcreteComponent.Operation()");
        }
    }
}
复制代码

  Decorator.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.DecoratorPattern.Structural
{
    public abstract class Decorator : Component
    {
        protected Component component;

        public void SetComponent(Component component)
        {
            this.component = component;
        }
        
        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }
}
复制代码

  ConcreteDecoratorA.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.DecoratorPattern.Structural
{
    public class ConcreteDecoratorA : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            Console.WriteLine("ConcreteDecoratorA.Operation()");
        }
    }
}
复制代码

  ConcreteDecoratorB.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatterns.DecoratorPattern.Structural
{
    public class ConcreteDecoratorB : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            AddedBehavior();
            Console.WriteLine("ConcreteDecoratorB.Operation()");
        }

        void AddedBehavior()
        {
        }
    }
}
复制代码

  Program.cs

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DesignPatterns.DecoratorPattern.Structural;

namespace DesignPatterns.DecoratorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create ConcreteComponent and two Decorators
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();

            // Link decorators
            d1.SetComponent(c);
            d2.SetComponent(d1);

            d2.Operation();
        }
    }
}
复制代码

  运行输出:

ConcreteComponent.Operation()
ConcreteDecoratorA.Operation()
ConcreteDecoratorB.Operation()
请按任意键继续. . .




4、装饰模式应用分析

  装饰模式适用情形:

   在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责

   处理那些可以撤销的职责

  装饰模式的特点:

   比静态类更灵活。使用装饰模式可以很容易地向对象添加职责的方式。可以用添加和分离的方法,对装饰在运行时添加和删除职责。相比之下,继承机制要求为每个添加的职责创建一个新的子类。这会产生很多新的类,并会增加系统的复杂度。

   使用装饰模式可以很容易地重复添加一个特性,而两次继承特性类则极容易出错。

   为了避免处理顶层的类有太多的特征。装饰模式下,你可以定义一个简单的类,并用装饰类给它逐渐地添加功能。这样可以从简单的部件组合出复杂的功能,具有低依赖性和地复杂性。

   有许多小对象。采用装饰模式进行系统设计往往会产生许多看上去类似的小对象,尽管对于了解这些系统的人来说,很容易进行定制,但是很难学习这些系统,排错很恶化呢困难。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多