装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
以下情况使用Decorator模式
1. 需要扩展一个类的功能,或给一个类添加附加职责。
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
如下:是王者荣耀的一个例子
/**
* 游戏里角色,包括英雄,小兵,野怪,防御塔等
* */
public interface GameObject {
}
/**
* 王者荣耀英雄猴子
* */
public interface SunWuKong {
//普通攻击
public void normalAttack(GameObject go);
}
/**
* 王者荣耀英雄猴子(未学技能)
* */
public class SunWuKong0Skill implements SunWuKong{
//普通攻击
@Override
public void normalAttack(GameObject go) {
System.out.println("平A了一下"+go);
}
}
/**
* 王者荣耀英雄猴子(学了1技能的装饰器)
* 这里可以用继承,后续只学了2技能的孙悟空也继承。
* 那么既学1技能又学2技能的呢?
* 后面还有3技能的呢?
* 再出装备呢?
* 不可能所有的孙悟空都去继承原始未学技能未出装备的孙悟空,这样同样的代码要写很多遍,同时会生成大量子类
* 那么我们用装饰模式,把原始的孙悟空放到不同的装饰器里,装饰之后的孙悟空仍然是孙悟空,学新技能把原来装饰过的孙悟空再装进新的装饰器即可
* */
public class SunWuKong1SkillDecorator implements SunWuKong{
SunWuKong sunWuKong;
public SunWuKong1SkillDecorator(SunWuKong sunWuKong){
this.sunWuKong = sunWuKong;
}
@Override
public void normalAttack(GameObject go) {
sunWuKong.normalAttack(go);
}
public void skill1Attack(GameObject go){
System.out.println("1技能打了一下"+go);
}
}
/**
* 王者荣耀英雄猴子(学了2技能的装饰器)
* */
public class SunWuKong2SkillDecorator implements SunWuKong{
SunWuKong sunWuKong;
public SunWuKong2SkillDecorator(SunWuKong sunWuKong){
this.sunWuKong = sunWuKong;
}
@Override
public void normalAttack(GameObject go) {
sunWuKong.normalAttack(go);
}
public void skill2Attack(GameObject go){
System.out.println("2技能打了一下"+go);
}
}
/**
* 王者荣耀英雄猴子(学了3技能的装饰器)
* */
public class SunWuKong3SkillDecorator implements SunWuKong{
SunWuKong sunWuKong;
public SunWuKong3SkillDecorator(SunWuKong sunWuKong){
this.sunWuKong = sunWuKong;
}
@Override
public void normalAttack(GameObject go) {
sunWuKong.normalAttack(go);
}
public void skill3Attack(GameObject go){
System.out.println("3技能打了一下"+go);
}
}
public class Main {
public static void main(String[] args) {
//原始孙悟空
SunWuKong sunWuKong = new SunWuKong0Skill();
//只学了1技能的孙悟空,此处可以根据条件判断先学的1技能还是2技能,用不同的装饰器即可
sunWuKong = new SunWuKong1SkillDecorator(sunWuKong);
//既学1技能又学2技能的孙悟空
sunWuKong = new SunWuKong2SkillDecorator(sunWuKong);
//既学1技能又学2技能还学3技能的孙悟空
sunWuKong = new SunWuKong3SkillDecorator(sunWuKong);
}
}
说明:装备系统也是装饰器模式,出了装备以后就是出了装备的孙悟空但与学技能不同的是,出完了的装备还可以卖掉。这里可以和责任链模式相结合,将所有装备装饰器串到责任链上。
普通猴子经过责任链处理变成六神装猴子,换装备时,删掉原有链表里的装饰器替换成新的装饰器即可。