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. POJ1446 Girls and Boys

    Girls and Boys Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 12747   Accepted: 5678 D ...

  2. 第32讲:List的基本操作实战与基于模式匹配的List排序算法实现

    今天来学习一下list的基本操作及基于模式匹配的排序操作 让我们从代码出发 val bigData = List("hadoop","spark") val d ...

  3. STL其他--<tuple>用法【C11】

     tuple 库 tuple 库 是能够将不同类型的对象组合起来形成一个对象.和pair 对象一样,但是可以组织多种不同类型的元素. tuple中的元素类型是在编译时期决定的.与<utility ...

  4. QT5.4.0安装以及与VS2010整合安装---64bit操作系统解决方案

    QT5.4.0安装以及与VS2010整合安装---64bit操作系统解决方案 注意,目前QT官网不能下载,必须提供注册,然后才可以下载. 网上不同版本安装的细节有差异,特将我的安装相关操作贴出来,希望 ...

  5. hdu 5099 简单模拟(比较型号)

    http://acm.hdu.edu.cn/showproblem.php?pid=5099 比较两个安卓手机型号,水题 注意点:A is actually implicit and usually ...

  6. POJ2828线段树单点更新——逆序更新

    Description 输入n个有序对< pi, vi >,pi表示在第pi个位置后面插入一个值为vi的人,并且pi是不降的.输出最终得到的v的序列 Input 多组用例,每组用例第一行为 ...

  7. yum-本地源配置(CentOS7)

    服务器版本查看:# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 一.挂载ISO文件: 1.ISO镜像下载网站:网易镜像: ...

  8. 前端开发 - JavaScript

    本节内容 一.如何编写 二.变量 三.数据类型 四.其他 五.语句与异常 六.函数 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScri ...

  9. 微擎开启性能优化里面的性能优化memcache内存优化及数据库读写分离

    http://www.mitusky.com/forum.php?mod=viewthread&tid=3135 [微擎 安装使用] 微擎开启性能优化里面的性能优化memcache内存优化及数 ...

  10. [控件]unigui移动端下Unidatepicker时间显示解决方案

    [控件]unigui移动端下Unidatepicker时间显示解决方案 http://tz10000.com/kong-jian-unigui-yi-dong-duan-xia-unidatepick ...