1  装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面向对象的设计中,而我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。装饰器模式的本质就是动态组合。动态是手段,组合才是目的。总之,装饰模式是通过把复杂的功能简单化,分散化,然后再运行期间,根据需要来动态组合的这样一个模式。
2  问题提出:在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?
这时我们就可以使用装饰器模式
同样的我们还是来举个例子看看:

设计一个小游戏 游戏中很多的角色(角色包括: 枪手Gunmen,刀客swordsman等), 角色拥有武器,武器包括(刀knife(150),枪gun(200),棍(100)),

游戏中我们可以通过给武器加上一些宝石(蓝宝石,红宝石,绿宝石) 来加强武器的攻击力。

红宝石每增加一颗 攻击力 +5;ruby

蓝宝石每增加一颗 攻击力+10;sapphire

绿宝石每增加一颗 攻击力 +20

结构图:

首先还是先创建两个接口;

 package ooad.design.Decorator;

 public interface IWeapon {
public String getName();
public int getAttack();
}
 package ooad.design.Decorator;

 public interface IRole {
public void attack(IWeapon weapon); }

接着我们创建武器:

 package ooad.design.Decorator;

 public class Gun implements IWeapon {
private String name; public Gun(String name) {
super();
this.name = name;
} @Override
public String getName() { return this.name;
} @Override
public int getAttack() { return 200;
} }

然后我们创建角色:

 package ooad.design.Decorator;

 public class Gunmen implements IRole {
private String name; public Gunmen(String name) {
super();
this.name = name;
}
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public void attack(IWeapon weapon) {
System.out.println(this.name+"使用"+weapon.getName()+"进行攻击,造成的伤害值为:"+weapon.getAttack());
} }

因为武器需要宝石来装饰,所以呢我们创建一个装饰的抽象类

 package ooad.design.Decorator;

 public abstract class Decorator implements IWeapon{
public abstract int getAttack(); }

宝石类:

 package ooad.design.Decorator;

 public class Ruby extends Decorator {
private IWeapon weapon; public Ruby(IWeapon weapon) {
super();
this.weapon = weapon;
} @Override
public String getName() { return "增加了红宝石的"+weapon.getName();
} @Override
public int getAttack() { return 5+weapon.getAttack();
} }

来个测试:

 package ooad.design.Decorator;

 public class Test {

     public static void main(String[] args) {
IRole r =new Gunmen("枪手");
IWeapon w=new Gun("火箭枪");
r.attack(w);
w=new Ruby(w);
r.attack(w);
} }

最终结果:

枪手使用火箭枪进行攻击,造成的伤害值为:200
枪手使用增加了红宝石的火箭枪进行攻击,造成的伤害值为:205

如果想要用两颗红宝石我们就可以这样:

r.attack(w);

r.attack(w);

结果呢则是:

枪手使用火箭枪进行攻击,造成的伤害值为:200
枪手使用增加了红宝石的增加了红宝石的火箭枪进行攻击,造成的伤害值为:210

增加了红宝石的增加了红宝石的  这样看起来不舒服吧,该怎样去判断他到底增加了几颗宝石,我们就显示几颗宝石呢?

例子中的角色,武器,装饰的宝石,我就没有全部写出来了!

装饰器(Decorator)模式的更多相关文章

  1. 装饰器(Decorator)模式

    public interface IDoThings { public void doSomeThing(); } public class DoThings implements IDoThings ...

  2. Head First 设计模式 —— 03. 装饰器 (Decorator) 模式

    思考题 有如下类设计: 如果牛奶的价钱上扬,怎么办?新增一种焦糖调料风味时,怎么办? 造成这种维护上的困难,违反了我们之前提过的哪种设计原则? P82 取出并封装变化的部分,让其他部分不收影响 多用组 ...

  3. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  4. python 装饰器(decorator)

    装饰器(decorator) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语 ...

  5. python语法32[装饰器decorator](转)

    一 装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现有的功能.其实也就是其他语言中的AOP的概念,将对象或函数的 ...

  6. Python的程序结构[8] -> 装饰器/Decorator -> 装饰器浅析

    装饰器 / Decorator 目录 关于闭包 装饰器的本质 语法糖 装饰器传入参数 1 关于闭包 / About Closure 装饰器其本质是一个闭包函数,为此首先理解闭包的含义. 闭包(Clos ...

  7. Python_高阶函数、装饰器(decorator)

    一.变量: Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来. 对变量赋值x = y是把变量 ...

  8. python 语法之 装饰器decorator

    装饰器 decorator 或者称为包装器,是对函数的一种包装. 它能使函数的功能得到扩充,而同时不用修改函数本身的代码. 它能够增加函数执行前.执行后的行为,而不需对调用函数的代码做任何改变. 下面 ...

  9. python函数编程-装饰器decorator

    函数是个对象,并且可以赋值给一个变量,通过变量也能调用该函数: >>> def now(): ... print('2017-12-28') ... >>> l = ...

  10. 【Angular专题】 (3)装饰器decorator,一块语法糖

    目录 一. Decorator装饰器 二. Typescript中的装饰器 2.1 类装饰器 2.2 方法装饰器 2.3 访问器装饰器 2.4 属性装饰器 2.5 参数装饰器 三. 用ES5代码模拟装 ...

随机推荐

  1. c#运用反射获取属性和设置属性值

    /// <summary> /// 获取类中的属性值 /// </summary> /// <param name="FieldName">&l ...

  2. 最短路 模板 【bellman-ford,dijkstra,floyd-warshall】

    Bellman-ford: /* bellman ford */ #include <iostream> #include <cstdio> #include <cstr ...

  3. SRM483

    250pt 题意:给定一个[0,1)间的实数,一个分母不超过maxDen的分数逼近.. 思路:直接枚举.然后判断. code: #line 7 "BestApproximationDiv1. ...

  4. Legal or Not HDU

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  5. CSS 基础 优先级 选择器 继承

    1.样式优先级 (内联样式)Inline style     >    (内部样式)Internal style sheet     >     (外部样式)External style ...

  6. Java设计模式详尽资料

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  7. 我的ecshop二次开发经验分享

    https://jingyan.baidu.com/article/358570f65dbad2ce4724fcc7.html

  8. SQL Server nested loop join 效率试验

    从很多网页上都看到,SQL Server有三种Join的算法, nested loop join, merge join, hash join. 其中最常用的就是nested loop join. 在 ...

  9. .NET MVC 学习笔记(三)— MVC 数据显示

    . NET MVC 学习笔记(三)—— MVC 数据显示 在目前做的项目中,用的最多的数据展示控件就是table展示(说不是的请走开,不是一路人),以下详细阐述下table的使用方法. 先看效果: 上 ...

  10. HttpWebRequest 跳转后(301,302)ResponseUri乱码问题

    问题: 目标地址: http://www.baidu.com/baidu.php?url=a000000aa.7D_ifdr1XkSUzuBz3rd2ccvp2mFoJ3rOUsnx8OdxeOeOL ...