版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Bronze5/article/details/90143456
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比集成更有弹性的代替方案。
设计原则
- 类应该对扩展开放,对修改关闭
举例说明
场景:在不修改现有代码的情况下,给对象搭配新的行为。
具体需求:英雄作战时,会受到敌方英雄各种各样的技能攻击,相应的英雄生命值逐渐降低。请设计一个可扩展的程序,来计算当前英雄受到攻击后的当前生命值,最好描述出英雄所受到的伤害。
- 抽象出一个基础组件(Hero)
/**
* 基础组件类
* @author: jsk
* @date: 2019/5/12 17:24
*/
public interface Hero {
/**
* 生命值
* @return
*/
Integer healthPoint();
String description();
}
- 抽象出一个实现基础组件的装饰者类
/**
* @author: jsk
* @date: 2019/5/12 17:39
*/
public abstract class AbstractEnemyHero implements Hero {
/**
* 攻击对象
*/
Hero targetHero;
}
-
分别实现以上两个抽象
3.1 实现基础组件类/** * @author: jsk * @date: 2019/5/12 17:30 */ public class Galen implements Hero { @Override public Integer healthPoint() { return 3000; } @Override public String description() { return "我是盖伦"; } }
3.2实现装饰者类
/** * 寒冰射手 * @author: jsk * @date: 2019/5/12 17:41 */ public class Ashe extends AbstractEnemyHero { public Ashe(Hero hero) { this.targetHero = hero; } @Override public Integer healthPoint() { return targetHero.healthPoint() - 90; } @Override public String description() { return targetHero.description() + ", 受到寒冰的普通攻击"; } }
/** * 卡特琳娜 * * @author: jsk * @date: 2019/5/12 17:52 */ public class Catalina extends AbstractEnemyHero { public Catalina(Hero hero) { this.targetHero = hero; } @Override public Integer healthPoint() { return targetHero.healthPoint() - 110; } @Override public String description() { return targetHero.description() + ", 受到卡特飞镖的攻击"; } }
4.程序运行
/**
* @author: jsk
* @date: 2019/5/12 17:53
*/
public class Main {
public static void main(String[] args) {
// 创建一个盖伦
Galen galen = new Galen();
// 经过艾希的装饰(攻击)
Ashe ashe = new Ashe(galen);
// 经过卡特的装饰(攻击)
Catalina catalina = new Catalina(ashe);
System.out.println(catalina.description());
System.out.println("目前总生命值:" + catalina.healthPoint());
}
}
运行结果
/