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. 用Html创建简历

    用最基本的html实现简历的创建 代码 <!doctype html> <html> <head><meta charset="utf-8" ...

  2. 用户访问网页流程、DNS 解析流程

    一.用户访问流程 二.DNS解析流程 DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于 TCP/IP 网络,它所提供的 ...

  3. 1.虚拟机中安装ubuntu

    1.VMware安装很简单,全部默认安装即可. 2.安装完VMware之后,打开VMware,点击创建虚拟机 典型安装易出问题,所以这里选择自定义安装 安装过程选项配置如下 处理器数,核数,内存都可以 ...

  4. 【图数据结构的遍历】java实现广度优先和深度优先遍历

    [图数据结构的遍历]java实现广度优先和深度优先遍历 宽度优先搜索(BFS)遍历图需要使用队列queue数据结构: 深度优先搜索(DFS, Depth First Search)的实现 需要使用到栈 ...

  5. 语音识别功能_微信小程序代办清单任务

    最近想给自己的代办清单任务微信小程序想加个语音识别识别功能,废话不多说,直接说重点,语音识别使用的是百度语音识别api,因为微信小程序的录音输入文件目前只能是mp3或aac 但是百度语音识别不支持这两 ...

  6. Stm32ADC-内部温度传感器的使用

    搞完了ADC的基本配置步骤,下面就是ADC配合一些外设的应用了,首先就是stm32f1内部的温度传感器通过adc采集获得温度; 内部温度传感器在ADC1的通道16上,所以只需要初始化以下ADC1就好了 ...

  7. 知物由学 | AI在Facebook清理有害内容上扮演了什么角色?

    "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物 ...

  8. Linux系统Bash的常用功能(9)

    了解了基本的Linux文件文件系统的概念后,我们将更深入的了解一下Linux的其他方面的内容,那就是我们所使用的用户接口,也就是大家常听到的 『Shell』 ,『这个shell并不是黑客反弹的shel ...

  9. Swift5 语言指南(二十二) 扩展

    扩展为现有的类,结构,枚举或协议类型添加新功能.这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模).扩展类似于Objective-C中的类别.(与Objective-C类别不同,Swift扩展 ...

  10. Java - 基础起步

    package basics; //声明该类所在的包为basics,package为包的关键字 import java.util.Date; //导入java.util包中的Date类,用来封装当前的 ...