博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式系列之「装饰模式」
阅读量:7125 次
发布时间:2019-06-28

本文共 3462 字,大约阅读时间需要 11 分钟。

**小Y:**Hello,大家好,欢迎来到魂斗罗.归来的世界,下面让小Y带领大家一起去采访一下叼烟大汉比尔·雷泽,让大家更加理解这个粗狂的战斗汉子。Let's go。!

**小Y:**你最喜欢干什么?

**比尔·雷泽:**最喜欢冲关打爆大机。

**小Y:**比尔,你想对观众说些什么?

**比尔·雷泽:**想挑战我,随时奉陪!一颗不够,给你来三颗!

小Y:......

比尔·雷泽作为魂斗罗这么经典的人物,原来也是一个粗狂耿直boy呀。为了保存住他的光辉形象和让大家更加了解他,小Y决定把比尔·雷泽的攻击技能装饰一番介绍给大家认识。

一、案例设想

**比尔·雷泽在战场上在战场上基本上用散弹枪可以横扫小兵,但是遇到一些特殊的情况还是需要通过G5手雷、集速手雷、爆破飞弹等技能来进行辅助。**那么如何设置这些技能才合适呢?简单,小Y脑海中立马闪过几种方案:

(1)采用继承的方式,设定一个比尔·雷泽类,有多少个技能就写多少个子类来继承这个比尔·雷泽类。

看完这个图,小Y自己都蒙逼了,每增加一个技能可以组合出N个子类,这只是一个比尔·雷泽,再来个艾薇、寒锋什么的,那不就要加到天荒地老?

(2)直接抽象一个角色类,里面包含了每个角色的技能。

这样子有多少个角色就增加多少个子类就可以了,不用根据技能增加类,避免造成子类爆炸,但是,每个角色的技能是可以叠加使用的,角色越多或者技能叠加种类越多,那么就要在超类增加越多的方法,而且直接修改超类不符合开闭原则(超类对扩展开放,对修改关闭)。

(3)今天的主题— 装饰模式。

二、装饰模式的概念

1.装饰模式定义

装饰模式(Decorator Pattern)是一种比较常见的模式,动态地给一个对象添加一些额外的职责(就增加功能来说,装饰模式相比生成子类更为灵活)。

2.使用的场景

  • 需要扩展一个类的功能,或者给一个类添加附加职责(即核心功能不变,对其进行扩展)。
  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实,使得子类数目呈爆炸性增长。

3.角色介绍

  • Component抽象构件

    Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象(在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当Component抽象构件) 。

  • ConcreteState具体状态角色

    ConcreteComponent 具体构件,是Component的具体实现,要装饰的就是它 。

  • Decorator装饰角色

    一般是一个抽象类,实现Component接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的属性里必然有一个private变量指向Component抽象构件(如果具体装饰角色只有一个,这个可以省略)。

  • ConcreteDecorator具体装饰角色

    把你最核心的、最原始的、最基本的东西装饰成想要的东西。

4.案例实现

(1)装饰模式实现角色装饰UML图

①抽象角色类

public abstract class Character {	public abstract void attack();} 复制代码

②实现角色比尔·雷泽(对它进行装饰)

public class BillRizer extends Character {	@Override	public void attack() {		//角色最基本的技能		System.out.print("散弹枪进行扫射!");	}}复制代码

③技能装饰抽象类

public abstract class SkillDecorator extends Character{	private Character character;	public SkillDecorator(Character character) {		this.character = character;	}	@Override	public void attack() {		this.character.attack();	}}复制代码

④G5手雷技能

public class G5GrenadeDecorator extends SkillDecorator {	public G5GrenadeDecorator(Character character) {		super(character);	}	@Override	public void attack() {		super.attack();		System.out.print("G5手雷辅助攻击!");	}}复制代码

⑤集速手雷技能

public class SetspeedDecorator extends SkillDecorator {	public SetspeedDecorator(Character character) {		super(character);	}	@Override	public void attack() {		super.attack();		System.out.print("集速手雷辅助!");	}}复制代码

⑥爆破飞弹技能

public class ExplosiveMissileDecorator extends SkillDecorator {	public ExplosiveMissileDecorator(Character character) {		super(character);	}	@Override	public void attack() {		super.attack();		System.out.print("爆破飞弹辅助!");	}}复制代码

⑦客户端

public class Client {	public static void main(String[] args){		//需要装饰的BillRizer		BillRizer billRizer=new BillRizer();		//使用G5手雷辅助		G5GrenadeDecorator g5GrenadeDecorator=new G5GrenadeDecorator(billRizer);		g5GrenadeDecorator.attack();			//使用G5手雷+集速手雷+爆破飞弹辅助		SetspeedDecorator setspeedDecorator=new SetspeedDecorator(g5GrenadeDecorator);		ExplosiveMissileDecorator explosiveMissileDecorator=new ExplosiveMissileDecorator(setspeedDecorator);		explosiveMissileDecorator.attack();	}}复制代码

输出结果:

①散弹枪进行扫射!G5手雷辅助攻击!②散弹枪进行扫射!G5手雷辅助攻击!集速手雷辅助!爆破飞弹辅助!复制代码

把比尔·雷泽的技能介绍一番,大家会发现原来这个看似粗狂的大汉真的霸气十足啊,有资格看你不爽就来一句“想挑战我,随时奉陪!一颗不够,给你来三颗”。

三、总结分析

  • 优点:

    ①装饰类和被装饰类可以独立发展,而不会相互耦合。Component类无须知道Decorator类,而Decorator也不用知道具体的构件,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。 ②装饰模式是继承关系的一个替代方案。装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。 ③通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。

  • 缺点:

    ①这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。 ②使用装饰模式进行系统设计时将产生很多小对象,这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。

看到装饰模式很多小伙伴会发现跟代理模式很相似,下一篇小Y会对这两种模式进行对比,请期待!!!!

简书地址:http://www.jianshu.com/p/d7a9208c6829

转载地址:http://pxoel.baihongyu.com/

你可能感兴趣的文章
vmware esxi基础篇之标准交换机
查看>>
mysql的binlog安全删除
查看>>
使用JDBC连接Mysql数据库
查看>>
IBM Java多线程 - 4.共享对数据的访问
查看>>
变态级JAVA程序员面试32问
查看>>
Java 8学习之Stream API
查看>>
app web技术选择
查看>>
ringtone播放自定义的声音
查看>>
电脑监控专家安装使用方法
查看>>
Dubbo详细介绍与安装使用过程
查看>>
http头分析
查看>>
[转载] Towards Alternative Approaches to Reasoning about Goals
查看>>
[转载] 中华典故故事(孙刚)——01 天要下雨_娘要嫁人
查看>>
mac 无法连接android手机进行调试 解决方案
查看>>
模式窗口和非模式窗口
查看>>
Linux搭建postfix邮件服务器
查看>>
JSTL+EL-----消灭java的JSP语言(去伪存精版)
查看>>
TCP/IP简要回顾
查看>>
JAVA设计模式之桥接模式
查看>>
Java基础学习总结(7)——Object类
查看>>