设计模式 装饰者模式

装饰者模式

概述

英文名:Decorator Pattern. 它是指在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰模式的特点

装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互.

装饰对象包含一个真实对象的引用(reference)

装饰对象接受所有来自客户端的请求,他把这些请求转发给真实对象

装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

适用性

以下情况试用Decorator模式

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("———————————");
    }
}

输出结果:
设计模式 装饰者模式_第1张图片
相信到这里,我们对装饰者模式有了一个清晰的认识。你也可以通过上述提到的JavaIO流深入体会装饰者模式,希望能在开发中多多体现吧。

你可能感兴趣的:(Java设计模式)