目录

  • 一个例子(贪玩蓝月)
  • 传统继承实现
  • 装饰器模式实现
  • 对比
  • 总结

Decorator(装饰器)模式属于结构型模式。
比如当其需要三种不同的附加特性,可以为其创建三个派生类。但是若它还需要同时具有其中两种特性或者是各种特性的任意组合的时候,类继承的方法就不再适合了。
它允许向一个现有的对象不通过继承来添加新的功能,同时又不改变其结构。

一个例子(贪玩蓝月)

前一阵子张家辉代言的《贪玩蓝月》广告火了,“我系喳喳辉,是兄弟就来砍我~”被洗脑到现在,正好用这个游戏来解释一下装饰器模式。

玩游戏的人都知道这种类传奇的游戏核心玩法就是买装备,打怪,升级,买装备这样反复。

刚注册账号进入游戏的玩家假设只有一条大裤衩,价值5金币,随着刷怪升级,身上的装备也在一件件增多,这时候我们需要知道身上的装备价值多少金币。

定义玩家

public interface Gamer {/*** 获取目前的装备* @return*/String getEquip();/*** 获取目前身上装备的价格* @return*/int getPrice();
}

定义具体的法师职业玩家

public class MasterGamer implements Gamer {/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return "大裤衩";}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return 5;}
}

新法师玩家出门只有大裤衩,装备全靠打。

传统继承实现

装备“法师权杖”

public class TruncheonMasterGamer extends MasterGamer{/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return super.getEquip()+",法师权杖";}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return super.getPrice()+50;}
}

继续装备“魔法斗篷”

public class CloakTruncheonMasterGamer extends TruncheonMasterGamer{/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return super.getEquip()+",魔法斗篷";}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return super.getPrice()+80;}
}

注意,这里是在之前已经装备了“法师权杖”之上去继承。

计算装备价格

CloakTruncheonMasterGamer gamer = new CloakTruncheonMasterGamer();
System.out.println("当前装备:"+gamer.getEquip()+"\n装备总价值:"+gamer.getPrice());

输出结果

当前装备:大裤衩,法师权杖,魔法斗篷
装备总价值:135

装饰器模式实现


声明通用装饰器基类“装备”

public abstract class Equip implements Gamer {private Gamer gamer;public Equip(Gamer gamer) {this.gamer = gamer;}/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return gamer.getEquip();}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return gamer.getPrice();}
}

具体装饰器“法师权杖”

public class Truncheon extends Equip {public Truncheon(Gamer gamer) {super(gamer);}/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return super.getEquip()+",法师权杖";}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return super.getPrice()+50;}
}

具体装饰器“魔法斗篷”

public class Cloak extends Equip {public Cloak(Gamer gamer) {super(gamer);}/*** 获取目前的装备** @return*/@Overridepublic String getEquip() {return super.getEquip()+",魔法斗篷";}/*** 获取目前身上装备的价格** @return*/@Overridepublic int getPrice() {return super.getPrice()+80;}
}

计算装备价格

//创建一个法师玩家
Gamer gamer = new MasterGamer();
//给法师玩家装备法师权杖
gamer = new Truncheon(gamer);
//给法师玩家装备魔法斗篷
gamer = new Cloak(gamer);
System.out.println("当前装备:"+gamer.getEquip()+"\n装备总价值:"+gamer.getPrice());

输出结果

当前装备:大裤衩,法师权杖,魔法斗篷
装备总价值:135

对比

上面例子比较简单,传统继承实现和装饰器模式实现区别不是很明显,但仔细思考还是会发现一些区别:

  • 传统继承实现不自由,没有“组件化”特性。玩家的装备是可以随意组合,随意拆卸的,而这种特性对于继承来说只能通过各种各样的子类组合来实现。就像上面的例子,装备“法师权杖”和“魔法斗篷”需要在拥有“法师权杖”的基础上再去继承。
  • 装饰器模式实现,使得附属属性和主体分开,而又不单独存在(Equip类里面声明了Gamer对象)。装备和玩家是分开的,可以给玩家单独装备任何装备,也可以随意卸下装备。

总结

这种设计模式下不仅可以扩展一个类的功能,也可以动态增加功能,动态撤销。但缺点就是多层装饰使用起来相对比较复杂。本质是将具体功能职责划分(例如区分核心组件以及附加属性职责)减少子类直接继承父类的耦合性。


你可以在这里获取相关代码:设计模式-Decorator模式

转载于:https://www.cnblogs.com/xuxiaojian/p/11468734.html

设计模式-Decorator模式相关推荐

  1. 设计模式-Decorator模式(装饰者模式)

    文章目录 装饰者模式 代码实现 为什么使用装饰者模式 装饰者模式 假如现在有一块蛋糕, 加上奶油就是奶油蛋糕.如果继续再加上草莓,就是草莓蛋糕,再加点蜡烛,就变成了生日蛋糕.不论是蛋糕.奶油蛋糕.草莓 ...

  2. GOF 设计模式 Decorator模式 笔记

    Decorator(装饰) 意图:动态的给一个对象添加一些额外的职责.就添加功能来说,Decorator模式相比生成子类更为灵活 结构图: 在以下情况适合使用 在不影响其他对象的情况下,以动态,透明的 ...

  3. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  4. 设计模式学习笔记——装饰(Decorator)模式

    设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...

  5. 【笔记整理】图解设计模式 | 第12章 Decorator模式(装饰边框与被装饰物的一致性)

    [笔记整理]图解设计模式 | 导航 定义 不断地为对象添加装饰的设计模式被称为Decorator模式,其中Decorator指的是"装饰物". Decorator模式中的登场角色 ...

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

    Java设计模式 -10- 装饰器模式(Decorator模式) 前言 装饰器模式的定义与特点 优点: 缺点: 装饰器模式的结构与实现 1. 模式的结构 2. 模式的实现 装饰器模式的应用实例 装饰器 ...

  7. 设计模式:装饰(Decorator)模式

    设计模式之装饰(Decorator)模式 在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修.相片加相框等.在软件开发过程中,有时想用一些现存的组件.这些组件可能只是完成了一些核心功 ...

  8. 设计模式--装饰者(Decorator)模式

    模式定义 动态(组合)地给一个对象增加一些额外的职责,就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码并且减少子类个数) 类图 应用场景 扩展一个类的功能或给一个类添加附 ...

  9. 设计模式学习每天一个——Decorator模式

    参考 http://www.cnblogs.com/god_bless_you/archive/2010/06/10/1755212.html 一.装饰模式: 顾名思义,就是对物品进行装饰,既然是装饰 ...

最新文章

  1. 使用pip将Python包安装到不同的目录中?
  2. 简明python教程txt-Python新手的数据批量处理教程(TXT文件)
  3. net下web开发人员要掌握哪些技术才算好
  4. java is a_java中 is - a和 has - a的区别
  5. C# 值类型的局限性
  6. 编程之美-2.17-数组循环移位
  7. linux输入yum后提示: -bash: /usr/bin/yum: No such file or directory的解决方案
  8. java一个引用多大_为什么Java 8为方法引用引入了一个新的“::”运算符?
  9. kmem 反编译linux内核_24小时学通Linux内核之如何处理输入输出操作
  10. python-学生管理系统--2录入学生信息内容以及代码
  11. mysql主键和外键的连接_MySQL主键和外键使用及说明
  12. 想用html5改写妄撮
  13. 00 Linux到底是什么?
  14. Wireshark-----抓包分析
  15. SCI和SCIE的区别和联系
  16. 新闻|花旗银行、阿联酋阿布札比投资局来访智链万源
  17. 我在美团Android研发岗工作的那5年,社招面试心得
  18. 童年神机小霸王(七) Mapper
  19. SSM框架:SpringMVC
  20. 史上最全,程序员必须掌握的400个编程英语词汇

热门文章

  1. 关于在本地idea当中提交spark代码到远程的错误总结(第二篇)
  2. [2018.3.30集训]path-对偶图-最小割
  3. python爬虫beautifulsoup4系列4-子节点
  4. hash集合方法使用
  5. (剑指Offer)面试题10:二进制中1的个数
  6. 使用.net调用java的Web Services
  7. 无法创建Web Application项目的问题
  8. VC#打包部署全攻略之(一、添加卸载程序)
  9. 浅谈SpringCloud (二) Eureka服务发现组件
  10. Tuple解决在视图中通过razor获取控制器传递给视图的匿名对象的报错问题