设计模式学习--装饰者模式(Decorator Pattern)

概念:

装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性.

解决方案:

装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有着相同的结构.这样一来,在运行的过程中,就可以将这些对象融合在一起,将相同的属性等成员有机的结合,就像生成另外一种类型一样,而实际上,我们并不需要真的创建这个类型,它是动态生成的.这些装饰者既可以组合,也可以撤销组合,既回复到原来对象状态.

示例介绍:

装饰者模式的关键就是装饰者类型的定义,而其中应包括组合操作的方法.

现在我们看一下装饰者接口的定义:

    /// <summary>
    /// 装饰者模式模型,接口
    /// </summary>
    public interface IDecorator
    {
        string Name { get; }
        int Sum { get; }
        void Add(IDecorator decorator);
    }

接下来是装饰者类CDecorator类的定义:

    /// <summary>
    /// 装饰者类
    /// </summary>
    public class CDecorator:IDecorator
    {
        private string myName;

        private int mySum;

        private ArrayList myDecorator;

        public CDecorator()
        {
            myName = "";
            mySum = 0;
            myDecorator = new ArrayList();
        }

        //只读属性,名称
        public string Name
        {
            get
            {
                string result = myName;
                foreach (IDecorator d in myDecorator)
                {
                    result += ", " + d.Name;
                }
                return myName;
            }
        }

        //只读属性,合计值
        public int Sum
        {
            get
            {
                int result = mySum;
                foreach (IDecorator d in myDecorator)
                {
                    result += d.Sum;
                }
                return mySum;
            }
        }

        //添加装饰者对象
        public void Add(IDecorator decorator)
        {
            myDecorator.Add(decorator);
        }
    }

下面我们通过代码测试下这个模型:

    //应用测试
    class Program
    {
        static void Main(string[] args)
        {
            CDecorator decoratorA = new CDecorator("decoratorA", 1);
            CDecorator decoratorB = new CDecorator("decoratorB", 2);
            CDecorator decoratorC = new CDecorator("decoratorC", 3);
            
            decoratorA.Add(decoratorB);
            decoratorA.Add(decoratorC);

            Console.WriteLine(decoratorA.Name);
            Console.WriteLine(decoratorA.Sum);

            Console.Read();
        }
    }

运行结果如下:

应用特点

使用装饰者模式时应注意以下特点:

  • 因装饰者模式一般用于动态组合对象,所以,他们一般都是临时性的,在这个模型中,我们并没有添加取消组合功能.如果需要,你可以在IDecorator接口中添加Remove()方法,并在CDecorator类中实现它.
  • 不需要创建新的类型,就可以修改对象的特性(如对象的各种属性值),从而影响了对象的行为,就像创建了一个新的对象类型一样.
  • 需要创建很多的相同结构的装饰者对象,以便于组合.

结束语

不要强硬的去理解设计模式,也不要强硬的去套用它的形式,你所要做的是理解它的技巧以及思想,慢慢体会你才会理解它的妙用,这是我的一点体会,希望大神多多拍砖.如果感觉不错,请推荐****

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏恰同学骚年

剑指Offer面试题:27.最小的k个数

  这道题是典型的TopK问题,其最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),但...

852
来自专栏机器人网

ABB机器人编程方式

1、指令表IL   指令表(IL)由一系列指令组成。每条指令都由一个新行开始,包含一个操作符以及和操作符类型相关的一个或多个操作数,并用逗号分开。在指令前可以有...

2946
来自专栏小樱的经验随笔

BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 1469  Solved: 63...

2554
来自专栏算法修养

PAT 1017 Queueing at Bank (模拟)

1017. Queueing at Bank (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B ...

2757
来自专栏自由而无用的灵魂的碎碎念

通过写Java代码来对MyEclipse进行注册

import java.io.BufferedReader; import java.io.IOException; import java.io...

1154
来自专栏数据结构与算法

BZOJ 3932: [CQOI2015]任务查询系统(主席树)

1290
来自专栏大数据学习笔记

Hadoop源码分析:HDFS读取文件

Hadoop源码分析:HDFS读取文件 上一篇博客http://blog.csdn.net/chengyuqiang/article/details/78636...

3936
来自专栏冷冷

【微信开发】 使用单例设计模式 提供AccessToken 和Jsapi_ticket缓存支持

上一篇 是使用ecache 做的缓存, 有些简单的微信项目并不需要这么复杂,所以就想到单例设计模式  首先,我们先定义一个单例对象 import java.ut...

1987
来自专栏木宛城主

SharePoint CAML In Action——Part II

在SharePoint中,相对于Linq to SharePoint而言,CAML是轻量化的。当然缺点也是显而易见的,"Hard Code"有时会让你抓狂。在实...

1775
来自专栏对角另一面

lodash源码分析之baseFindIndex中的运算符优先级

本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

1908

扫码关注云+社区