Java设计模式:装饰者模式

装饰者模式:

允许向一个已经创建的对象添加新的功能,同时又不改变其结构。装饰者模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰器类,用来包装原有的类,并在保持原类方法完整性的前提下,提供了额外的功能。

一般的结构如下UML类图:
在这里插入图片描述
Component是一个抽象父类,ConcreteComponent是其具体子类,负责具体实现父类的方法;
Decorator是一个装饰器类,聚合了Component类,有Component类的属性,ConcreteDecoratorA和ConcreteDecoratorB分别为其装饰器具体实现类。

说完了抽象层面,我们来举个具体的例子来实现。
想必大家也玩过游戏,我们以游戏角色为例,结构如下:
在这里插入图片描述
Role为抽象类,仅仅定义相关的属性与抽象方法,这里我只定义了一个抽象方法data()调用toString方法

public abstract class Role {
    private String job;
    private int attack;
    private int defence;
    public abstract void data();
	
	//getter、setter方法,可快速扫过
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }
    public int getAttack() {
        return attack;
    }
    public void setAttack(int attack) {
        this.attack = attack;
    }
    public int getDefence() {
        return defence;
    }
    public void setDefence(int defence) {
        this.defence = defence;
    }

    @Override
    public String toString() {
        return "Role{" +
                "job='" + job + '\'' +
                ", attack=" + attack +
                ", defence=" + defence +
                '}';
    }
}

具体实现类Fighter(战士),通过构造函数初始化面板属性:

public class Fighter extends Role {
    @Override
    public void data() {
        System.out.println(super.toString());
    }

    public Fighter() {
        setJob("战士");
        setAttack(10);
        setDefence(10);
    }
}

同样的实现类Wizard(法师):

public class Wizard extends  Role{
    @Override
    public void data() {
        System.out.println(super.toString());
    }
    public Wizard() {
        setJob("法师");
        setAttack(15);
        setDefence(5);
    }
}

接下来是Decorator(装饰器)类,继承Role,并且把Role类的对象作为其私有属性,通过传入Role参数初始化:

public class Decorator extends Role {
    private Role role = null;
    public Decorator(Role role) {
        this.role = role;
    }
    @Override
    public void data() {
        role.data();
    }
}

接下来是装饰器类的具体实现类Sword(剑),构造器传入Role参数。
这里为了简单说明仅仅只是用一个构造器加简单的打印语句代表已添加了装饰。

public class Sword extends Decorator {
    public Sword(Role role) {
        super(role);
        System.out.println("装备上了武器——剑,攻击力提升了10:");
        role.setAttack(role.getAttack()+10);
        super.data();
    }
}

同样的实现类Shield(盾):

public class Shield extends Decorator {
    public Shield(Role role) {
        super(role);
        System.out.println("装备上了防具——盾牌,防御力提升了10:");
        role.setDefence(role.getDefence()+10);
        super.data();
    }
}

现在来看看最后如何实现装饰者模式的调用操作吧:
动态的添加新功能附加在原始的对象上面去,通过传入对象为参数:

public class Client {
    public static void main(String[] args) {
        //新建战士对象
        //构造器里赋初始属性
        Role fighter = new Fighter();
        //显示面板属性
        fighter.data();
        //装配——剑
        fighter = new Sword(fighter);

        System.out.println();

        //新建战士对象
        //构造器里赋初始属性
        Role wizard = new Wizard();
        //显示面板属性
        wizard.data();
        //装配——盾牌
        wizard = new Shield(wizard);
    }
}

得到输出结果:

Role{job='战士', attack=10, defence=10}
装备上了武器——剑,攻击力提升了10:
Role{job='战士', attack=20, defence=10}

Role{job='法师', attack=15, defence=5}
装备上了防具——盾牌,防御力提升了10:
Role{job='法师', attack=15, defence=15}

总结

  • 功能:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)。
  • 关键: 1、Component 类充当抽象角色,不应具体实现。 2、修饰者类引用和继承 Component 类,具体扩展类重写父类方法。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值