【设计模式】装饰者模式:以造梦西游的例子讲解一下装饰者模式,这也是你的童年吗?
创始人
2024-02-04 08:54:28
0

文章目录

  • 1 概述
    • 1.1 问题
    • 1.2 定义
    • 1.3 结构
    • 1.4 类图
  • 2 例子
    • 2.1 代码
    • 2.2 效果图
  • 3 优点及适用场景
    • 3.1 优点
    • 3.2 适用场景

1 概述

1.1 问题

众所周知,造梦西游3有四个角色,也就是师徒四人,这师徒四人每个人都有自己专属的武器和装备。假定我们以及设计出来了Role(角色类),并通过继承的方式创造出来了师徒四人的角色(这里只写两个)。

image-20221120232302990

那么这时候问题来了,如果给角色增加一个武器,该怎么实现呢》

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FmLn58Qi-1668959273768)(https://gitee.com/you-tanzhi/pic/raw/master/u=846442474,698297682&fm=253&fmt=auto&app=138&f=JPEG)]

我想你头脑中第一印象会想到继承

如下,创建两个武器九尺钉耙和金箍棒

在这里插入图片描述

image-20221120232824246

这样九尺钉耙和金箍棒就和角色联系起来了,这时候你可以很清晰的发现,如果在增加一个武器,如月牙弓,你就需要分别创建两个子类。如果再增加一个新角色,如沙僧的话,又要增加更多的子类,这实在是太麻烦。就在你疑惑不解,大骂恶心的时候,我们本篇文章的主角装饰者模式闪亮登场了。

1.2 定义

装饰者模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

1.3 结构

装饰者模式有四个角色:

  • 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  • 具体构建角色(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  • 抽象装饰(Decorator)角色:继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构建的功能。
  • 具体装饰角色(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

1.4 类图

image-20221120234046978

2 例子

2.1 代码

Role.java

public abstract class Role {/* 攻击力 */private float aggressivity;/* 描述 */private String explain;/* 计算攻击力的方法 */public abstract float calculate();public Role(float aggressivity, String explain) {this.aggressivity = aggressivity;this.explain = explain;}public float getAggressivity() {return aggressivity;}public void setAggressivity(float aggressivity) {this.aggressivity = aggressivity;}public String getExplain() {return explain;}public void setExplain(String explain) {this.explain = explain;}
}

Equipment.java

public abstract class Equipment extends Role{/* 角色的变量 */Role role;public Equipment(float aggressivity, String explain, Role role) {super(aggressivity, explain);this.role = role;}public Role getRole() {return role;}public void setRole(Role role) {this.role = role;}
}

Wukong.java

public class WuKong extends Role{public WuKong() {super(150, "孙悟空");}public float calculate() {return getAggressivity();}
}

Bajie.java

public class BaJie extends Role{public BaJie() {super(80, "猪八戒");}public float calculate() {return getAggressivity();}
}

GoldHoopRod.java

public class GoldHoopRod extends Equipment{public GoldHoopRod(Role role) {super(90, "金箍棒", role);}public float calculate() {return getAggressivity()+role.calculate();}public String getExplain() {return super.getExplain()+role.getExplain();}
}

NineToothRake.java

public class NineToothRake extends Equipment{public NineToothRake(Role role) {super(60, "九尺钉耙", role);}public float calculate() {return getAggressivity()+role.calculate();}public String getExplain() {return super.getExplain()+role.getExplain();}
}

Player.java

package com.you.Demo19;public class Player {public static void main(String[] args) {Role role = new WuKong();System.out.println("原始的角色:"+role.getExplain()+"  的战斗力  "+role.getAggressivity());System.out.println("---------------------------");/* 猴哥拿起金箍棒的战斗力 */role = new GoldHoopRod(role);System.out.println(role.getExplain()+"  "+role.calculate());/* 猴哥拿起九尺钉耙+金箍棒的战斗力 */role = new NineToothRake(role);System.out.println("---------------------------");System.out.println(role.getExplain()+" "+role.calculate());/* 猪八戒拿起支持钉耙~战斗力 */System.out.println("----------------------------");Role role1 = new BaJie();role1 = new NineToothRake(role1);System.out.println(role1.getExplain()+"   "+role1.calculate());}
}

2.2 效果图

image-20221120231737061

3 优点及适用场景

3.1 优点

  • 装饰者模式可以带来比继承更具灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果,装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继承是静态的附加责任,装饰者是动态的附加责任。
  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态拓展一个实现类的功能。

3.2 适用场景

  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时(主要有两类)
    • 第一类是系统中存在大量独立的拓展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
    • 第二类是因为类定义不能继承(如Final类)
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 当对象的功能要求可以动态添加,也可以再动态地撤销时。

在本例子中,指的就是把装备类删掉,并不影响原有的代码。

  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时(主要有两类)
    • 第一类是系统中存在大量独立的拓展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
    • 第二类是因为类定义不能继承(如Final类)
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 当对象的功能要求可以动态添加,也可以再动态地撤销时。

在本例子中,指的就是把装备类删掉,并不影响原有的代码。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...