英文名:Decorator Pattern. 它是指在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
1、需要扩展一个类的功能,或者给一个类添加附加职责
2、需要动态的给一个对象添加功能,这些功能可以再动态撤销
3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实
4、当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可以是因为类定义被隐藏,或类定义不能用于生成子类
1、Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性
2、通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合
JavaIO流
下面我将配合代码说明装饰着模式的各个角色
这里我选取的是游戏中的例子
1、抽象构件(component):给出一个抽象接口,以规范准备接口附加责任的对象
/**
* 装备的接口
*/
public interface IEquip {
/**
* 攻击力的计算
*/
public int caculateAttack();
/**
* 装备的描述
*/
public String description();
}
2、具体构件(concrete component):定义一个将要接受附加责任的对象
实现上述的装备接口,
然后分别是武器,戒指,护腕,鞋子
/**
* 武器
*/
public class ArmEquip implements IEquip {
@Override
public int caculateAttack() {
return 20;
}
@Override
public String description() {
return "倚天剑";
}
}
/**
* 戒指
* */
public class RingEquip implements IEquip{
@Override
public int caculateAttack() {
return 5;
}
@Override
public String description() {
return "vip皇冠戒指";
}
}
/**
* 护腕
* */
public class WristEquip implements IEquip {
@Override
public int caculateAttack() {
return 5;
}
@Override
public String description() {
return "圣战护腕";
}
}
/**
* 鞋子
* */
public class ShoeEquip implements IEquip{
@Override
public int caculateAttack() {
return 5;
}
@Override
public String description() {
return "圣战靴子";
}
}
3、装饰角色(decorator):持有一个构件对象的实例,并实现一个与抽象构建接口一致的接口
装饰接口扩展功能
public interface IEquipDecorator extends IEquip{
}
4、具体装饰角色(concrete decorator):负责给构件对象添加上附加的责任
接下来是装饰类
public class BlueGemDecorator implements IEquipDecorator{
/**
* 蓝宝石
* */
private IEquip equip; //构建对象的实例
public BlueGemDecorator(IEquip equip) {
super();
this.equip = equip;
}
@Override
public int caculateAttack() {
return 5 + equip.caculateAttack();
}
@Override
public String description() {
return equip.caculateAttack() + " + 蓝宝石";
}
}
public class RedGemDecorator implements IEquipDecorator{
private IEquip equip;
public RedGemDecorator(IEquip equip) {
super();
this.equip = equip;
}
@Override
public int caculateAttack() {
return 15 + equip.caculateAttack();
}
@Override
public String description() {
return equip.description() + " + 红宝石";
}
}
public class YellowGemDecorator implements IEquipDecorator{
private IEquip equip;
public YellowGemDecorator(IEquip equip) {
super();
this.equip = equip;
}
@Override
public int caculateAttack() {
return 10 + equip.caculateAttack();
}
@Override
public String description() {
return equip.description() + "+ 黄宝石";
}
}
好了到现在装饰模式的各个角色已经就位,下面来测试一下:
public class Test {
public static void main(String[] args) {
//一个向前两颗红宝石,1颗蓝宝石的靴子
System.out.println("一个镶嵌两颗红宝石,1颗蓝宝石的靴子");
IEquip equip = new RedGemDecorator(new RedGemDecorator(new BlueGemDecorator(new ShoeEquip())));
System.out.println("攻击力 :" + equip.caculateAttack());
System.out.println("描述:" + equip.description());
System.out.println("--------------");
equip = new RedGemDecorator(new YellowGemDecorator(new BlueGemDecorator(new ArmEquip())));
System.out.println("一个镶嵌一个红宝石,一个蓝宝石,一个黄宝石的武器");
System.out.println("攻击力 :" + equip.caculateAttack());
System.out.println("描述:" + equip.description());
System.out.println("———————————");
}
}
输出结果:
相信到这里,我们对装饰者模式有了一个清晰的认识。你也可以通过上述提到的JavaIO流深入体会装饰者模式,希望能在开发中多多体现吧。