设计模式 装饰者模式

来源:互联网 发布:搞怪美图软件 编辑:程序博客网 时间:2024/05/21 10:10

装饰者模式

概述

英文名: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("———————————");    }}

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

0 0
原创粉丝点击