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设计模式》之装饰者模式
一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...
随机推荐
- 03.28,周六,12:00-17:00,ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016正式赛。
A. Majestic 10 题意:三个数均大于10则输出"triple-double",如果两个数大于10则输出"double-double",如果一个大于1 ...
- 爬虫:HTTP请求与HTML解析(爬取某乎网站)
1. 发送web请求 1.1 requests 用requests库的get()方法发送get请求,常常会添加请求头"user-agent",以及登录"cookie&q ...
- 手写Spring MVC框架(二) 实现访问拦截功能
前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...
- activiti知识点梳理
一.Activiti是什么 Alfresco 软件在 2010 年 5 月17 日宣布 Activiti业务流程管理(BPM)开源项目的正式启动,其首席架构师由业务流程管理 BPM的专家 Tom Ba ...
- 30.Stream流
5.Stream流 5.1体验Stream流[理解] 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以"张"开头的元素存储到一个新的集 ...
- JSX语法详解
一.基础1.JSX是什么JSX是一种像下面这样的语法: const element = <h1>Hello, world!</h1>;1它是一种JavaScript语法扩展,在 ...
- Spring Cloud Alibaba(12)---Gatway概述、简单示例
Gatway概述.项目搭建 前言 有关网关的概念之前这里不在概述,因为之前在写zuul网关的时候有详细陈述过,地址如下: SpringCloud(7)---网关概念.Zuul项目搭建 SpringCl ...
- [刷题] 349 Intersection of Two Arrays
查找问题 查找有无(只有键) 元素'a'是否存在 set(集合) 查找对应关系(键值对应) 元素'a'出现了几次 map(字典) set和map的底层实现是红黑树 常见操作 insert() find ...
- wps中新罗马字体如何设置Times New Roman
word wps中新罗马字体如何设置Times New Roman ### WPS字体自带 Times New Roman ###
- ARM64平台编译stream、netperf出错解决办法 解决办法:指定编译平台为alpha [root@localhost netperf-2.6.0]# ./configure –build=alpha
ARM64平台编译stream.netperf出错解决办法 http://ilinuxkernel.com/?p=1738 stream编译出错信息: [root@localhost stream]# ...