重看Decorator Pattern,联想到Delegate传递及Flags Enum--欢迎拍砖!
话说装饰模式(Decorator)的动机是“动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。[GOF 《设计模式》]”。再次学到该模式,有感,联想到Delegate和Flags Enum。Delegate也可实现在已有功能上动态添加新功能,有点”装饰“的意图,Flags Enum可以进行组合使用。如果对装饰模式不熟悉,请移步大神博文http://terrylee.cnblogs.com/archive/2006/03/01/340592.html。本文描述该模式的相关思考,不正之处,请大神指点拍砖!谢谢
该模式的UML图:
,Decorator抽象,既继承Component又组合引用Component,为什么需要这样呢?从该模式的具体代码看到,装饰之上可以继续装饰,故需要引用一个装饰,为什么有需要继承呢,感觉装饰需要一个抽象吧。
现在来假设一个场景,有一个现有的对象,如下:
public class Component
{
public void Operation(string msg)
{
Console.WriteLine("Compent.Operation。hi,:"+msg);
}
}
该操作不是可override的,那怎么使用装饰模式来扩展新功能呢?这里给出装饰模式的“变形代码”
public class ComponentWrapper
{
public virtual void Operation(string msg)
{
Component m_Component = new Component();
m_Component.Operation(msg);
}
} public class ComponentWrapper1 : ComponentWrapper
{
private ComponentWrapper m_decorator;
public ComponentWrapper1(ComponentWrapper decorator)
{
m_decorator = decorator;
}
public override void Operation(string msg)
{
m_decorator.Operation(msg);
Add(msg);
}
public static void Add(string msg)
{
Console.WriteLine("ComponentWrapper1 added");
}
} public class ComponentWrapper2 : ComponentWrapper
{
private ComponentWrapper m_decorator;
public ComponentWrapper2(ComponentWrapper decorator)
{
m_decorator = decorator;
}
public override void Operation(string msg)
{
m_decorator.Operation(msg);
Add(msg);
}
public static void Add(string msg)
{
Console.WriteLine("ComponentWrapper2 added");
}
}
//调用代码
ComponentWrapper d = new ComponentWrapper();//未装饰
ComponentWrapper d1 = new ComponentWrapper1(d);//装饰上功能1
ComponentWrapper d2 = new ComponentWrapper2(d1);//装饰上功能2 d2.Operation("stevey");
上面代码中,ComponentWrapper 作为装饰的基类,对已有功能进行包装,在装饰1中继承装饰基类又包含一个装饰。可能说包装感觉更形象一点,一层一层的包装,或者说人穿的衣服也是一层一层的,哈哈。可以看到,一个装饰对象就作为一个”功能集“整体,实际上是一个引用装饰链,调用依次传递到顶端。由此联想到,功能也可以追加,功能也可以做成像链式依次执传递。遵循上面场景的方法契约,于是就凭着感觉写出如下code:
public static class ComponentExtension
{
/// <summary>
/// 在已有操作之后加上新操作
/// </summary>
/// <param name="action">原操作</param>
/// <param name="otherAction">新操作</param>
/// <returns></returns>
public static Action<string> After(this Action<string> action,Action<string> otherAction)
{
return (msg) => {
action(msg);
otherAction(msg);
};
} public static Action<string> Before(this Action<string> action, Action<string> otherAction)
{
return (msg) =>
{
otherAction(msg);
action(msg);
};
}
}
调用代码:
//使用delegate装饰新功能
Action<string> action = new Component().Operation;
Action<string> wrapper1 = action.After(ComponentWrapper1.Add);//装饰上功能1
Action<string> wrapper2 = wrapper1.After((msg) =>//装饰上功能2
{
Console.WriteLine("wrapper2 added");
});
wrapper2("hello");
Console.WriteLine("*****************************");
//
Action<string> wrapper3 = wrapper1.After(wrapper2);
wrapper3("(原功能+功能1)+{(原功能+功能1)+装饰上功能2}");//在已有的装饰整体上加上另一个装饰
上面的代码可以链式,其他不解释了,代码是最直接的意思表达,在一个功能上继续包装一个功能,得到的就是一个装饰,可以作为整体,继续装饰。。。貌似比模式轻量级点不。
标记枚举,也有点”装饰“的味道,MSDN上的代码:
[Flags]
enum Days2
{
None = 0x0,
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
//Flags Enum
// Initialize with two flags using bitwise OR.
var meetingDays = Days2.Tuesday | Days2.Thursday; // Set an additional flag using bitwise OR.
meetingDays = meetingDays | Days2.Friday; Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Tuesday, Thursday, Friday // Remove a flag using bitwise XOR.
meetingDays = meetingDays ^ Days2.Tuesday;
Console.WriteLine("Meeting days are {0}", meetingDays);
// Output: Meeting days are Thursday, Friday
就写到这里吧,感觉有点语无伦次,不在状态,大家就将就看吧。算是一点装饰模式的读后感,欢迎大家讨论,不正之处,还请指出,谢谢!
重看Decorator Pattern,联想到Delegate传递及Flags Enum--欢迎拍砖!的更多相关文章
- 第 13 章 装饰模式【Decorator Pattern】
以下内容出自:<<24种设计模式介绍与6大设计原则>> Ladies and gentlemen,May I get your attention,Please?,Now I’ ...
- C#设计模式之八装饰模式(Decorator Pattern)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第三个模式,该模式是[装饰模式],英文名称:Decorator Pattern.我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- 浅谈设计模式--装饰者模式(Decorator Pattern)
挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...
- .NET设计模式(10):装饰模式(Decorator Pattern)
.NET设计模式(10):装饰模式(Decorator Pattern) 装饰模式(Decorator Pattern) --.NET设计模式系列之十 年月..在....对于..由于使用装饰模 ...
- 设计模式系列之装饰模式(Decorator Pattern)
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...
- NET设计模式 第二部分 结构性模式(9):装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) ——.NET设计模式系列之十 Terrylee,2006年3月 概述 在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特 ...
- 设计模式学习--装饰者模式(Decorator Pattern)
概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
随机推荐
- SQLite入门与分析(三)---内核概述(1)
写在前面:从本章开始,我们开始进入SQLite的内核.为了能更好的理解SQLite,我先从总的结构上讨论一下内核,从全局把握SQLite很重要.SQLite的内核实现不是很难,但是也不是很简单.总的来 ...
- 八大排序方法汇总(选择排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序、堆排序,归并排序,计数排序)
2013-08-22 14:55:33 八大排序方法汇总(选择排序-简单选择排序.堆排序,插入排序-简单插入排序.shell排序,交换排序-冒泡排序.快速排序,归并排序,计数排序). 插入排序还可以和 ...
- CenOS7.1安装VNC——让win7远程桌面linux
参考:http://wic.xingning.gov.cn/blog/29 https://linux.cn/article-5335-1.html 1.检查是否安装VNC, rpm -q tiger ...
- Oracle命令(一):Oracle登录命令
1.运行SQLPLUS工具 C:\Users\wd-pc>sqlplus 2.直接进入SQLPLUS命令提示符 C:\Users\wd-pc>sqlplus /nolog 3.以OS身份连 ...
- javascript里的post和get有什么区别
FORM中的get post方法区别Form中的get和post方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法.二者主要区别如下: 1.Get是用来从服务器上获得数据,而Post ...
- 【HDOJ】1699 The comment in cpp
注意测试数据12/*hduacm// abcd结果是1/*hduacm// ABCD /* 1699 */ #include <iostream> #include <sstream ...
- FreeMarker中if标签内的判断条件
reeMarker中的<#if>标签除了里面直接判断 boolean 类型的变量外,也可以进行表达式判断,有几个细节记录一下 1. 判断对象是否存在(null) 经常会用到,如果对象 != ...
- Gentoo源码安装图解
Gentoo源码安装 一.前期准备 (1)下载以下三个文件 二.配置安装环境 (1)用光盘引导到LiveCD环境 (2)配置当前LiveCD环境的网络 安装Gentoo时,服务器引导的LiveCD环境 ...
- [.NET MVC进阶系列0x] EF Code First 数据迁徙(Migrations)
[因] Entity Framework中使用Code First模式进行开发时,数据库是基于Models中的类自动生成的(生成时间:第一次运行MVC项目时), 每次更改Models中类结构,重新编译 ...
- ubuntu桌面右上角键盘图标不见解决方法
今天出现了这个问题,桌面右上角的键盘图标不见,找到解决方法如下: 打开终端,分别输入以下命令即可: killall ibus-daemon 这个表示结束进程 ibus-daemon -d 这个表示重启 ...