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设计模式》之装饰者模式
一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...
随机推荐
- ConcurrentHashMap源码解读三
今天首先讲解helpTransfer方法 final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) ...
- 关于MySQL参数,这些你要知道
前言: 在前面一些文章中,经常能看到介绍某某参数的作用,可能有些小伙伴仍搞不清楚 MySQL 参数是啥.本篇文章我们来聊聊 MySQL 参数,学习下如何管理维护 MySQL 参数. 1.MySQL参数 ...
- Form-OCR & CSDNAPP初体验
项目 内容 课程:北航2020春软件工程 博客园班级博客 作业:阅读并撰写博客回答问题 软件案例分析 我在这个课程的目标是 全面地评价一个软件 这个作业在哪个具体方面帮助我实现目标 明确软件开发过程中 ...
- 『动善时』JMeter基础 — 14、使用JMeter发送Post请求
目录 1.Post请求参数类型说明 2.用于演示的项目说明 3.发送Post请求示例 (1)测试计划内包含的元件 (2)请求参数类型为x-www-form-urlencoded 4.请求参数form- ...
- 什么是CPU缓存
一.什么是CPU缓存 1. CPU缓存的来历 众所周知,CPU是计算机的大脑,它负责执行程序的指令,而内存负责存数据, 包括程序自身的数据.在很多年前,CPU的频率与内存总线的频率在同一层面上.内存的 ...
- VMware虚拟机性能优化
一.ESX及vCenter服务器的优化 检查ESX物理服务器是否在兼容列表中,特别是BIOS的版本是否符合ESX版本的要求 开启ESX物理服务器硬件虚拟化技术VT-X,AMD-V 关闭BIOS中的英特 ...
- Jira/Confluence配置Apache SSL 证书
1. 申请证书 生成私钥 openssl genrsa -out server.key 2048 生成request文件 openssl req -new -key server.key -out s ...
- 目录和文件 按创建时间排序du -h --time --max-depth=1 . |sort -r -t $'\t' -k 2 Linux查看文件夹大小,并按文件夹创建时间排序
目录和文件 按创建时间排序 # du -h --time --max-depth=1 . |sort -r -t $'\t' -k 230M 2020-04-01 14:54 .28K 2020-04 ...
- 云计算OpenStack---创建实例(11)
创建实例时,需要先创建网络及实例类型等其它配置: 一.创建虚拟网络(Self-service network) 网络概述图: 网络连接图: 1.创建self-service网络 (1)加载系统变量: ...
- Scala 函数式编程思想
Spark 选择 Scala 作为开发语言 在 Spark 诞生之初,就有人诟病为什么 AMP 实验室选了一个如此小众的语言 - Scala,很多人还将原因归结为学院派的高冷,但后来事实证明,选择 S ...