写这个随笔时,其实对该模式理解的并不是十分透彻。在此想到什么写什么,希望对自己对他人有所帮助。

装饰者模式主要是应用继承和组合的思想,极大的实现了程序的多态,使得的程序有了更高的扩展性。

  第一个基础例子:

这里假如我们要实现有这么一群人,他们都要穿西服。那么我们首先建立这个人类。

  代码如下:

   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#设计模式学习之装饰者模式的更多相关文章

  1. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  2. 设计模式学习之装饰者模式(Decorator,结构型模式)(16)

    参考地址:http://www.cnblogs.com/zhili/p/DecoratorPattern.html 一.定义:装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相 ...

  3. 设计模式学习(三): 装饰者模式 (附C#实现)

    需求 做一个咖啡店的订单系统. 买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等.咖啡店会根据调料的不同收取不同的费用.订单系统要考虑这些. 初版设计 然后下面就是所有的咖啡....: cost方法 ...

  4. Java-马士兵设计模式学习笔记-装饰者模式

    Java装饰者模式简介 一.假设有一个Worker接口,它有一个doSomething方法,Plumber和Carpenter都实现了Worker接口,代码及关系如下: 1.Worker.java p ...

  5. 设计模式学习系列6 原型模式(prototype)

    原型模式(prototype)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.允许一个对象再创建另外一个新对象的时候根本无需知道任何创建细节,只需要请求圆形对象的copy函数皆可. 1 ...

  6. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  7. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  8. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  9. 【读书笔记】读《JavaScript设计模式》之装饰者模式

    一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...

随机推荐

  1. Job for ssh.service failed because the control process exited with error code. See "systemctl status ssh.service" and "journalctl -xe" for details.

    1.按照提示 systemctl status ssh.service 查看报错原因 sshd -t 2.结果 /etc/ssh/sshd_config line 34: missing argume ...

  2. pgrep cron

    # pgrep cron947[root@localhost cron]# pgrep --help Usage: pgrep [options] <pattern> Options: - ...

  3. Lombok 插件安装和使用

    引言 以前的 Java 项目中,充斥着太多毫无技术含量的代码,比如类属性的 getter/setter/toString 方法,还有就是异常处理.I/O 流的关闭操作等.这些样板代码虽然可以通过 ID ...

  4. ubuntu中软件的升级管理-(转自Josh_)

    给Ubuntu软件升级命令 sudo apt-get update  --更新软件源 sudo apt-get upgrade -更新已经安装的软件 以非root用户更新系统 sudo: sudo是l ...

  5. s40 KVM虚拟化企业级实战

    1-为何使用虚拟化 02-KVM虚拟化环境准备 yum install libvirt* virt-* qemu-kvm* -y [root@cs7-kvm ~]# systemctl start l ...

  6. JavaEE 前后端分离以及优缺点

    前端概念 前端是一切直接与用户交互的页面或软件(用户看得见.摸得着)的统称,比如各种网站网页.andorid 手机各种 App.苹果手机各种 app.微信小程序.网络游戏客户端等.所以,普通人使用计算 ...

  7. 为何存在uwsgi还要使用nginx

    nginx是对外的服务接口,外部浏览器通过url访问nginx,nginx接收到浏览器发送过来的http请求,将包解析分析url,如果是静态文件则直接访问用户给nginx配置的静态文件目录,直接返回用 ...

  8. 吐血整理!Python常用第三方库,码住!!!

    ​ Python作为一种编程语言近年来越来越受欢迎,它为什么这么火? 其中一个重要原因就是因为Python的库丰富--Python语言提供超过15万个第三方库,Python库之间广泛联系.逐层封装.几 ...

  9. 自动驾驶QNX,Linux,Autosar概述

    自动驾驶QNX,Linux,Autosar概述 QNX是一个分布式.嵌入式.可规模扩展的实时操作系统.遵循POSIX.1 (程序接口)和POSIX.2 (Shell和工具).部分遵循POSIX.1b( ...

  10. MindSpore基本原理

    MindSpore基本原理 MindSpore介绍 自动微分 自动并行 安装 pip方式安装 源码编译方式安装 Docker镜像 快速入门 文档 MindSpore介绍 MindSpore是一种适用于 ...