C#设计模式学习之装饰者模式
写这个随笔时,其实对该模式理解的并不是十分透彻。在此想到什么写什么,希望对自己对他人有所帮助。
装饰者模式主要是应用继承和组合的思想,极大的实现了程序的多态,使得的程序有了更高的扩展性。
第一个基础例子:
这里假如我们要实现有这么一群人,他们都要穿西服。那么我们首先建立这个人类。
代码如下:
class Person
{
private string name; //要装扮的人的名称
public Person()
{ }
public Person(string _name)
{
this.name = _name;
}
public virtual void Show() //注意此处是虚方法
{
Console.WriteLine("装扮的人是:{0}", this.name);
}
}
然后构建西服类,代码如下
class Suit:Person
{
Person component = null; //穿西服的人 public void Decorate(Person _component) //把要穿西服的人传递到该类(组合思想)
{
this.component = _component;
}
public override void Show()
{
//如果有穿西服的人
if (component != null)
{
component.Show();
}
Console.WriteLine("穿上西服");
}
}
假如我们给小明和小红分别穿上西服,Main方法的代码如下
static void Main(string[] args)
{
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Suit suit = new Suit(); //装扮小明
suit.Decorate(xiaoming);
suit.Show(); //装扮小红
suit.Decorate(xiaohong);
suit.Show(); Console.ReadKey();
}
运行结果如下

类图结构如下

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第二个基础例子:
假如此时需求变了,我们的不仅要给小明和小红穿西服,我们还要给小狗阿黄穿西服,那该如何修改原程序呢。
开始扩展代码
此时我们新建一个Animal的抽象类
abstract class Animal //抽象的Animal类
{
protected string name;
public Animal()
{ }
public Animal(string _name)
{
this.name = _name;
}
public abstract void Show(); //原来Person的虚方法则改为对应的抽象方法
}
然后我们继续新建Person类和Dog类,都继承Animal类
class Person : Animal //人类,继承自Animal类
{
public Person(string _name) : base(_name)
{ }
public override void Show() //实现Animal类的抽象方法
{
Console.WriteLine("装扮的人{0}", base.name);
}
}
class Dog : Animal //够类,继承自Animal类
{
public Dog(string _name) : base(_name)
{ }
public override void Show() //实现Animal类的抽象方法
{
Console.WriteLine("装扮的狗{0}", base.name);
}
}
接下来我们分别给小明小红和阿黄穿上西服
static void Main(string[] args)
{
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Dog ahuang = new Dog("阿黄"); //装扮小明和小红
Suit suit = new Suit();
suit.Decorate(xiaoming);
suit.Show();
suit.Decorate(xiaohong);
suit.Show();
//装扮阿黄
suit.Decorate(ahuang);
suit.Show(); Console.ReadKey();
}
运行结果如下

类结构图如下,此时我们可以看到人和狗都继承自Animal,实现了一次的扩展的

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第三个基础例子
此时我们不仅想让小明小红阿黄穿西服了,我们还想让他们穿鞋子,打领带,并且以后可能会有更多的衣服供他们选择(变成奇迹暖暖了);
我们在第二个例子的基础上继续修改,满足需求
此时,我们将原来的Suit类改成抽象的衣服类,然后分别让Suit,Shoes和Sneake类继承自衣服类来实现
首先构造衣服类,代码如下
class Finery : Animal //此处继承Animal的抽象类,从而实现了所有类都继承自Animal类,在Derorate组合获得的component的字段,都可以使用Show()方法,从而达到一层一层装扮的目的
{ protected Animal component;
public void Decorate(Animal _component) //注意:此处是组合的思想,主要是为了把要修饰的主体放到该类的component字段中
{
this.component = _component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
然后分别构造西服,鞋子,领带类,代码如下
class Sneake : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("系上领带");
}
}
class Shoes : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("穿上鞋子");
}
}
class Suit : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("穿上西服");
}
}
接下来开始给小红小明和阿黄装扮,代码如下
static void Main(string[] args)
{
//实例化所有被装饰的主体
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Dog ahuang = new Dog("阿黄");
//实例化所有装饰
Suit suit = new Suit();
Sneake sneake = new Sneake();
Shoes shoes = new Shoes(); suit.Decorate(xiaoming);
sneake.Decorate(suit);
shoes.Decorate(sneake);
shoes.Show();
Console.WriteLine();
suit.Decorate(xiaohong);
sneake.Decorate(suit);
shoes.Decorate(sneake);
shoes.Show();
Console.WriteLine();
//狗就不系领带了
shoes.Decorate(ahuang);
suit.Decorate(shoes);
suit.Show(); Console.ReadKey();
}
运行结果如下:

类图结构如下

总结:
装饰者模式的难点在于多继承,存在组合的思想,将最高层次的被继承的类(Animal)组合(Decorate)在装饰类(Finery)中,通过base.Show()方法来一层一层的展现(这点有点绕,很像俄罗斯套娃,需要跟一下程序,一开始不太好理解)。
最后,如果有其他错误,欢迎指出,谢谢
C#设计模式学习之装饰者模式的更多相关文章
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 设计模式学习之装饰者模式(Decorator,结构型模式)(16)
参考地址:http://www.cnblogs.com/zhili/p/DecoratorPattern.html 一.定义:装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相 ...
- 设计模式学习(三): 装饰者模式 (附C#实现)
需求 做一个咖啡店的订单系统. 买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等.咖啡店会根据调料的不同收取不同的费用.订单系统要考虑这些. 初版设计 然后下面就是所有的咖啡....: cost方法 ...
- Java-马士兵设计模式学习笔记-装饰者模式
Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...
- 设计模式学习系列6 原型模式(prototype)
原型模式(prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个新对象的时候根本无需知道任何创建细节,只需要请求圆形对象的copy函数皆可. 1 ...
- JAVA设计模式之【装饰者模式】
JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- Java设计模式12:装饰器模式
装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
- 【读书笔记】读《JavaScript设计模式》之装饰者模式
一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...
随机推荐
- Nifi:初识nifi
写在前面: 第一次接触这一系统的时候,只有github上的一坨源码和官方的英文文档,用起来只能说是一步一个坑,一踩一个脚印,现在回想那段血泪史,只想 ***,现在用起来算是有了一些经验和总结,这里就做 ...
- 1. Java概述
1.1 Java语言背景介绍(了解) 语言:人与人交流沟通的表达方式. 计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言. Java语言是美国Sun公司(Stanford University ...
- Tomcat的使用和配置
Tomcat的使用 安装 在tomcat官网找到你需要用的 Tomcat 版本对应的 zip 压缩包,解压到需要安装的目录即可 目录介绍 bin : 专门用来存放Tomcat服务器的可执行文件 con ...
- TCP/IP协议三次握手_四次挥手
TCP/IP协议 TCP是一种面向连接的端到端的可靠传输协议. TCP报头格式 三次握手的过程 一.客户端发送一个连接请求,发送一个随机数X,这时客户端的端口状态变为SYN_SENT状态. 二.服务端 ...
- 创建第一个django工程
一.环境搭建 使用anaconda + pycharm的环境. 1.创建虚拟环境并安装django1.8的包 # 创建虚拟环境 conda create -n django python=3.6 # ...
- openresty 学习笔记二:获取请求数据
openresty 学习笔记二:获取请求数据 openresty 获取POST或者GET的请求参数.这个是要用openresty 做接口必须要做的事情.这里分几种类型:GET,POST(urlenco ...
- Python+Selenium自动化-定位一组元素,单选框、复选框的选中方法
Python+Selenium自动化-定位一组元素,单选框.复选框的选中方法 之前学习了8种定位单个元素的方法,同时webdriver还提供了8种定位一组元素的方法.唯一区别就是在单词elemen ...
- ZooKeeper学习笔记二:API基本使用
Grey ZooKeeper学习笔记二:API基本使用 准备工作 搭建一个zk集群,参考ZooKeeper学习笔记一:集群搭建. 确保项目可以访问集群的每个节点 新建一个基于jdk1.8的maven项 ...
- 无监督域对抗算法:ICCV2019论文解析
无监督域对抗算法:ICCV2019论文解析 Drop to Adapt: Learning Discriminative Features for Unsupervised Domain Adapta ...
- 如何写新的Python OP
如何写新的Python OP Paddle 通过 py_func 接口支持在Python端自定义OP. py_func的设计原理在于Paddle中的Tensor可以与numpy数组可以方便的互相转换, ...