可以简单理解:装饰者模式 = 策略模式 + 装饰类
策略模式的抽象类为被修饰类
ps:这只是入门,企业应用已优化,而且很精妙。
装饰者模式:
package com.decoration3;
/**
* 装饰者模式:对一个方法,进行多个扩展。需要哪个,调用哪个
*/
public interface Fight {
void attack();
void defense();
}
package com.decoration3;
public class FightImpl1 implements Fight {
@Override
public void attack() {
System.out.println("杀");
}
@Override
public void defense() {
System.out.println("受到攻击,出闪");
}
}
package com.decoration3;
public class FightImpl2 implements Fight {
@Override
public void attack() {
System.out.println("雷杀");
}
@Override
public void defense() {
System.out.println("受到攻击,喝酒加血");
}
}
package com.decoration3;
public class FightImpl3 implements Fight {
@Override
public void attack() {
System.out.println("火杀");
}
@Override
public void defense() {
System.out.println("受到攻击,丢弃一张手牌,转移伤害");
}
}
//被修饰类
package com.decoration3;
public abstract class FightWrapper implements Fight {
private Fight fight;
public void setFight(Fight fight) {
this.fight = fight;
}
@Override
public void attack() {
fight.attack();
}
@Override
public void defense(){
fight.defense();
}
}
//装饰类
package com.decoration3;
public class FightWrapperUse extends FightWrapper {
public Fight fight;
public void setFight(Fight fight) {
this.fight = fight;
}
@Override
public void attack() {
fight.attack();
System.out.println("触发被动技能,每出一张杀,摸一张手牌");
}
@Override
public void defense(){
fight.defense();
incomeCardForDefense();
}
public void incomeCardForDefense(){
System.out.println("每受到一次攻击,摸一张手牌");
}
/* public void defense(){
System.out.println("每受到一次攻击,摸一张手牌");
}*/
}
// 测试
package com.decoration3;
public class Test1 {
public static void main(String[] args) {
// 抽象类 XXX = new 装饰类
FightWrapperUse fightWrapperUse = new FightWrapperUse();
FightImpl1 fightImpl1 = new FightImpl1();
FightImpl2 fightImpl2 = new FightImpl2();
FightImpl3 fightImpl3 = new FightImpl3();
fightWrapperUse.setFight(new FightImpl1());
fightWrapperUse.attack();
fightWrapperUse.defense();
}
}
策略模式
package com.strategy;
/**
* 可以从多个方式中,任意选择一种方式,对一名角色发起攻击
*
*
*
* 装饰者模式和策略模式的不同在于,原有类和装饰器类必须继承同一个父类。
* 装饰器对象除了需要完成持有对象的操作外,还有一些附加操作,这些附加操作随着装饰器的不同而变化。
* 持有对象本身的操作是主体,装饰器的操作是补充。
* 而策略模式中,具体策略才是主体。
* @author wangfanghao
*/
public interface Fight {
/**
* XXX
*/
void attack();
}
package com.strategy;
public class Strategy1 implements Fight{
@Override
public void attack() {
System.out.println("南蛮入侵,掉血");
}
}
package com.strategy;
public class Strategy2 implements Fight{
@Override
public void attack() {
System.out.println("万箭齐发,掉血");
}
}
package com.strategy;
public class Strategy3 implements Fight{
@Override
public void attack() {
System.out.println("决斗,掉血");
}
}
package com.strategy;
/**
* Context存在的意义:解耦合,在测试类中,我们看不到底层方法的执行
* @author wangfanghao
*/
public class Context {
private Fight fight;
public void setFight(Fight fight) {
this.fight = fight;
}
public void execute(){
fight.attack();
}
}
package com.strategy;
public class Test {
public static void main(String[] args) {
Strategy1 strategy1 = new Strategy1();
Strategy2 strategy2 = new Strategy2();
Strategy3 strategy3 = new Strategy3();
Context context = new Context();
context.setFight(strategy1);
context.setFight(strategy2);
context.setFight(strategy3);
context.execute();
// 为什么不用下边这个?
/*
Strategy1 strategy1 = new Strategy1();
strategy1.attack();
*/
}
}
比较:
共有:
在不同类或包中,同一个策略和装饰类,new很多次,造成内存浪费。
解决:缓冲池
先new好,存到容器中。init,只new一次
策略缺点:熟悉每个策略
装饰者缺点:代码多,类多,程序复杂
不同:
策略:实现类 侧重于实现
装饰者:实现类 + 修饰类 侧重于修饰
ps:这只是入门,企业应用已优化,而且很精妙。