还是那几句话:

学无止境,精益求精

十年河东,十年河西,莫欺少年穷

学历代表你的过去,能力代表你的现在,学习代表你的将来

废话不多说,直接进入正题:

今天学习了装饰模式,但是代码看不太懂,于是我将装饰模式的代码改编成了如下代码:

如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SJMS
{
public abstract class Component
{
public abstract void Operation();
} public abstract class Deaorator : Component
{ public void SetComponent(Component component)
{
component.Operation(); }
} public class ConcreteDeaoratorC : Deaorator
{ public override void Operation()
{
Console.WriteLine("具体装饰对象C的操作");
}
} public class ConcreteDeaoratorA : Deaorator
{
private string addedState; public override void Operation()
{
addedState = "New State";
Console.WriteLine("具体装饰对象A的操作");
}
} public class ConcreteDeaoratorB : Deaorator
{
public override void Operation()
{
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
} private void AddedBehavior()
{ }
}
}

客户端代码如下:

        static void Main(string[] args)
{ ConcreteDeaoratorA a = new ConcreteDeaoratorA();
ConcreteDeaoratorB b = new ConcreteDeaoratorB();
ConcreteDeaoratorC c = new ConcreteDeaoratorC();
//
a.SetComponent(a);
b.SetComponent(b);
c.SetComponent(c);
//
Console.ReadKey();
}

针对上述的代码,自己又思索了一番,猛然间想到了设计模式:策略模式,再看看上述的代码,感觉是策略模式的升级版,呵呵。

我之前写的策略模式博客原文如下:商场促销-策略模式(和简单工厂模式很像的哇) C#

大家对比下,是不是比之前的策略模式还要简单?

OK,言归正传,之所有有上述的理解,说明我对装饰模式还是不太理解!

现在把装饰模式的代码贴出来,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SJMS
{
public abstract class Component
{
public abstract void Operation();
} public class ConcreteComponent : Component
{ public override void Operation()
{
Console.WriteLine("具体对象操作"); }
} public abstract class Deaorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
} public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
} public class ConcreteDeaoratorA : Deaorator
{
private string addedState; public override void Operation()
{
base.Operation();
addedState = "New State";
Console.WriteLine("具体装饰对象A的操作");
}
} public class ConcreteDeaoratorB : Deaorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
} private void AddedBehavior()
{ }
}
}

客户端调用如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SJMS
{
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDeaoratorA d1 = new ConcreteDeaoratorA();
ConcreteDeaoratorB d2 = new ConcreteDeaoratorB();
//
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
//
Console.ReadKey();
}
}
}

现在贴出上述代码的UML类图:

大话设计模式中程杰老师给出的定义,装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

可以看出:

装饰模式是利用SetComponent 来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离了,每个装饰对象值关心自己功能,不需要关心如何被添加到对象链当中。

装饰模式,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类的中重复的装饰逻辑。

亦可以看出:

各个子类都有自己独特的特性,比如:ConcreteDeaoratorA 类拥有私有属性:addedState ,ConcreteDeaoratorB 类用于自己的行为:AddedBehavior() 函数。总之,子类继承了父类,但同时也扩展了父类没有的行为属性。

因此我们得出如下结论(装饰模式的应用场景):

当系统需要新功能的时候,是向旧类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为。通常需要在父类中加入新的字段,新的方法和新的逻辑,从而增加了主类的复杂度。而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。

于是,为了这种特定的、特殊的、特有的属性/行为,装饰模式呼之欲出......

而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

装饰模式的优点:把类中装饰功能从类中搬移去除,这样可以简化原有的类;有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。

注意:装饰器的顺序至关重要

今天,我们结合具体的例子来说明(大话设计模式采用的例子是菜鸟见美眉,不同的衣服搭配来讲解装饰模式的):

代码如下:

    /// <summary>
/// 人类
/// </summary>
public abstract class Person
{
public abstract void Operation();
} public class Deaorator : Person
{
public string Name;
public Deaorator() { }
public Deaorator(string name)
{
this.Name = name;
}
protected Person person;
public void SetComponent(Person _person)
{
this.person = _person;
} public override void Operation()
{
if (person != null)
{
person.Operation();
}
}
} public class 大体恤 : Deaorator
{
public override void Operation()
{
Console.WriteLine("大体恤");
base.Operation();
}
} public class 破球鞋 : Deaorator
{
public override void Operation()
{
Console.WriteLine("破球鞋");
base.Operation();
}
} public class 大裤衩 : Deaorator
{
public override void Operation()
{
Console.WriteLine("大裤衩");
base.Operation();
}
} public class 小裤头 : Deaorator
{
public override void Operation()
{
Console.WriteLine("小裤头");
base.Operation();
}
}

调用代码如下:

namespace SJMS
{
class Program
{
static void Main(string[] args)
{
Deaorator d = new Deaorator("陈卧龙");
Console.WriteLine("陈卧龙的装扮如下:");
大体恤 c = new 大体恤();
破球鞋 d1 = new 破球鞋();
大裤衩 d2 = new 大裤衩();
小裤头 d3 = new 小裤头();
//
d1.SetComponent(c);
d2.SetComponent(d1);
d3.SetComponent(d2);
d3.Operation();
//
Console.ReadKey();
}
}
}

输出如下:

OK,先穿小裤头,再依次穿大裤衩、破球鞋,大体恤。这个穿戴顺序还可以哈!

将代码修改如下:

    class Program
{
static void Main(string[] args)
{
Deaorator d = new Deaorator("陈卧龙");
Console.WriteLine("陈卧龙的装扮如下:");
大体恤 c = new 大体恤();
破球鞋 d1 = new 破球鞋();
大裤衩 d2 = new 大裤衩();
小裤头 d3 = new 小裤头();
//
d1.SetComponent(c);
d3.SetComponent(d1);
d2.SetComponent(d3);
d2.Operation();
//
Console.ReadKey();
}
}

这样陈卧龙的小裤头就穿在外边了!呵呵,似乎有点不妥!因此,装饰的顺序很重要!

另外,整个装饰过程是一次性完成的,关键代码体现在: base.Operation();

@陈卧龙的博客

设计模式:装饰模式(decorate)的更多相关文章

  1. 设计模式--装饰模式Decorate(结构型)

    一.装饰模式 动态地给一个对象添加额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.有时我们希望给某个对象而不是整个类添加一些功能. 二.UML图 1.Component(概念中提到的对象接口 ...

  2. 设计模式 装饰模式(Decorator)

    设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...

  3. c++设计模式----装饰模式

    前言 在实际开发时,你有没有碰到过这种问题:开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作:而有一些非核心的操作,可能会使用,也可能不会使用:现在该怎么办呢? 将这 ...

  4. 深入浅出设计模式——装饰模式(Decorator Pattern)

    模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...

  5. Java设计模式---装饰模式

    装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户 ...

  6. C++设计模式——装饰模式

    前言 在实际开发时,你有没有碰到过这种问题:开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作:而有一些非核心的操作,可能会使用,也可能不会使用:现在该怎么办呢? 将这 ...

  7. 设计模式—装饰模式的C++实现

    这是Bwar在2009年写的设计模式C++实现,代码均可编译可运行,一直存在自己的电脑里,曾经在团队技术分享中分享过,现搬到线上来. 1. 装饰模式简述 1.1 目的 动态地给一个对象添加一些额外的职 ...

  8. <人人都懂设计模式>-装饰模式

    书上,真的用一个人穿衣打拌来讲解装饰模式的呢. from abc import ABCMeta, abstractmethod class Person(metaclass=ABCMeta): def ...

  9. [工作中的设计模式]装饰模式decorator

    一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...

  10. Java设计模式-装饰模式(Decorator)

    顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...

随机推荐

  1. 安卓开发-设置RadioButton的点击效果

    在安卓开发中用到底部菜单栏 需要用到RadioButton这个组件 实际应用的过程中,需要对按钮进行点击,为了让用户知道是否点击可这个按钮,可以设置点击后 ,该按钮的颜色或者背景发生变化. layou ...

  2. Android Studio:Support Library依赖包的版本号

    当我们用RecyclerView时,如果想用某一个特定的版本,怎样才能知道版本号呢?如果自己的笔记本中用过这个库,那么会保存在本地硬盘中. Android自身依赖包的版本号本地存放路径:  没有用过该 ...

  3. 模拟开户接口,使用python脚本实现批量用户开通

    1.目的 通过模拟接口方法,实现批量用户开通 2.分析 A.接口含body和head部分,其中body中的某些变量为必填字段,包含用户的信息. B.用户信息清单可以整理成ott_after_check ...

  4. 【PAT】B1002 写出这个数

    思路: 1.以字符串形式输入数据,计算结果 2.使用sprintf将结果数字转换为字符串(将数字每一位分开) 3.分别输出字符每一位 1,笨方法,用的ifelse来判断输出 #include<s ...

  5. SQL注入的绕过

    一.常用符号的绕过 1.空格 1 空格代替:+ %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ 2 括号绕过:常用于基于时间延迟的盲注,例如构造语句: ?id=1 ...

  6. 17秋 软件工程 团队第五次作业 Alpha Scrum4

    17秋 软件工程 团队第五次作业 Alpha Scrum4 今日完成的任务 世强:部门基础信息模块数据更新.部门审核提交: 港晨:设计编写登录界面的一部分: 树民:学习python基本语法.flask ...

  7. 17秋 软件工程 第六次作业 Beta冲刺 总结博客

    题目:团队作业--Beta冲刺 17秋 软件工程 第六次作业 Beta冲刺 总结博客 Beta冲刺过程中各个成员的贡献百分比 世强:15.5% 陈翔:14.5% 树民:12.0% 媛媛:14.0% 港 ...

  8. 面转栅格之ERROR 999999:执行函数时出错

    今天进行矢量面转栅格的操作时,总是出现ERROR 999999:执行函数时出错,如下图所示: 刚开始以为是栅格保存的路径太长的问题,后来发现是矢量面的路径问题,我的矢量面是放在自建的图层组下面,如下图 ...

  9. 玩转FusionCharts:Y轴数字形式(如去掉K)

    玩转FusionCharts:Y轴数字形式(如去掉K) 如果运行FusionCharts带的例子,你会发现FusionCharts表中的数字(通常是Y轴)会带上’k’,也就是如20000,会变成20k ...

  10. MySql常用命令集Mysql常用命令showdatabases;显示数据库createdatab

    MySql 常用命令集 Mysql常用命令 show databases; 显示数据库 create database name; 创建数据库 use databasename; 选择数据库 drop ...