装饰模式在王者荣耀中的应用
一、简述
在王者荣耀这款游戏中,英雄在战场上高伤害、高爆发、高移速等是所有玩家共同追求的,那么这些所谓的伤害、移速、穿透力等英雄属性我们可以通过在局外对英雄附带皮肤、配置合适的铭文;以及在局内通过购买装备等多种形式为我们的英雄增加伤害、移速。
像这种动态地对英雄额外增加皮肤、铭文、装备的方式提高伤害就可以通过“装饰模式”来实现。
玩过王者荣耀的人都知道,司马懿这个英雄作战能力是很强的,为了更出色地实现这个英雄在对局中的效果,在本例中,我们要对英雄司马懿从皮肤、铭文、装备三个层面提高他的作战和续航能力。
因为是三个层面,我们就在具体装饰角色中创建三个类去实现它:
①皮肤层面:皮肤可以给英雄带来10点的攻击加成;
②铭文层面:5级铭文梦魇、心眼、狩猎各10个(150级)是针对司马懿这一刺客类法师所推荐的;
③装备层面:攻速鞋+虚无法杖+吸血书+帽子+法穿杖+名刀/辉月的出装可以有效提高其在局内作战的效果
同时在本例中,我们简单地从攻速、移速、法伤、物伤四个角度看待这些方面的提升。
二、装饰模式(Decorator Pattern)
装饰模式理解:
动态地给对象添加一些额外的职责。就功能来说装饰模式相比生成子类更为灵活。
装饰模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。
装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中的最重要的两个角色。
装饰模式结构中的四种角色:
抽象组件(Component) :是一个抽象类,定义了“被装饰者”需要进行“装饰的方法”
具体组件(ConcreteComponent) :是抽象组件的一个子类,其实例被称为“被装饰者”
装饰(Decorator):也是抽象组件的一个子类(可抽象,可非抽象)
具体装饰(ConcreteDecotator):是装饰的一个非抽象子类,其实例被称为“装饰者”
装饰模式的UML类图:
装饰模式的优缺点:
优点:
①被装饰者和装饰者是松耦合关系
②装饰模式满足“开-闭原则”
③可以使用多个具体装饰来装饰具体组件的实例
缺点:
多层的装饰比较复杂
三、王者荣耀角度下实现装饰模式结构图及代码
实现此装饰模式的UML类图
eclipse结构图
主函数【应用(Application)】
Application.java
package angle_decorator;
/*
应用类
*/
import angle_decorator.Application;
import angle_decorator.Hero;
import angle_decorator.SimaYi;
import angle_decorator.SimaYiDecorator;
public class Application {
public void needSimayiPifu(Hero hero){
double SimayiAttribute1=hero.attribute1();
System.out.println("");
System.out.println("英雄司马懿换上“魇语军师”皮肤后的状态属性:");
System.out.println("法术伤害: "+SimayiAttribute1);
System.out.println("物理伤害:179.0");
System.out.println("移动速度:370.0");
System.out.println("攻速加成:0.0%");
System.out.println("--------------------------------------------------");
}
public void needSimayiMingwen(Hero hero){
double SimayiAttribute1=hero.attribute1();
double SimayiAttribute2=hero.attribute2();
double SimayiAttribute3=hero.attribute3();
System.out.println("");
System.out.println("英雄司马懿在拥有皮肤的基础上再装配150级铭文后的状态属性:");
System.out.println("法术伤害: "+SimayiAttribute1);
System.out.println("物理伤害:179.0");
System.out.println("移动速度:"+SimayiAttribute2);
System.out.println("攻速加成:"+SimayiAttribute3+"%");
System.out.println("--------------------------------------------------");
}
public void needSimayiZhuangbei(Hero hero){
double SimayiAttribute1=hero.attribute1();
double SimayiAttribute2=hero.attribute2();
double SimayiAttribute3=hero.attribute3();
double SimayiAttribute4=hero.attribute4();
System.out.println("");
System.out.println("英雄司马懿在拥有皮肤和150级铭文的基础上再装备6神装后的状态属性:");
System.out.println("法术伤害: "+SimayiAttribute1);
System.out.println("物理伤害:"+SimayiAttribute4);
System.out.println("移动速度:"+SimayiAttribute2);
System.out.println("攻速加成:"+SimayiAttribute3+"%");
}
public static void main(String[] args) {
System.out.println("");
System.out.println("英雄司马懿初始状态属性:");
System.out.println("法术伤害:0.0");
System.out.println("物理伤害:179.0");
System.out.println("移动速度:370.0");
System.out.println("攻速加成:0.0%");
System.out.println("---------------------------------------------------");
Application client=new Application();
Hero simayi=new SimaYi(); //司马懿初始状态属性
Hero simayiDecorator1=new SimaYiDecorator(simayi); //换上“魇语军师”皮肤后的状态属性
client.needSimayiPifu(simayiDecorator1);
Hero simayiDecorator2=new SimaYiDecoratorMingWen(simayi); //150级铭文后的状态属性
client.needSimayiMingwen(simayiDecorator2);
Hero simayiDecorator3=new SimaYiDecoratorZhuangBei(simayi); //6神装后的状态属性
client.needSimayiZhuangbei(simayiDecorator3);
}
}
抽象组件(Component)
Hero.java
package angle_decorator;
/*
角色1:抽象组件
*/
public abstract class Hero {
public abstract double attribute1(); //属性1:法伤
public abstract double attribute2(); //属性2:移速
public abstract double attribute3(); //属性3:攻速
public abstract double attribute4(); //属性4:物伤
}
具体组件(ConcreteComponent)
SimaYi.java
package angle_decorator;
/*
角色2:具体组件
*/
public class SimaYi extends Hero{
public final double AbilityPower=0; //AP(法术伤害)
public final double AttackPower=179; //AD(物理伤害)
public final double MovementSpeed=370; //移速
public final double AttackSpeed=0; //攻速
public double attribute1(){
return AbilityPower;
}
public double attribute2(){
return AttackPower;
}
public double attribute3(){
return MovementSpeed;
}
public double attribute4(){
return AttackSpeed;
}
}
装饰(Decorator)
Decorator.java
package angle_decorator;
/*
角色3:装饰
*/
import angle_decorator.Hero;
public abstract class Decorator extends Hero{
protected Hero hero;
public Decorator(){
}
public Decorator(Hero hero){
this.hero=hero;
}
}
具体装饰(ConcreteDecorator)
SimaYiDecorator.java
package angle_decorator;
/*
角色4.1:具体装饰 :皮肤属性加成
*/
import angle_decorator.Hero;
import angle_decorator.Decorator;
public class SimaYiDecorator extends Decorator{
public final double PiFuAddAbilityPower=10; //换上“魇语军师”皮肤后的法术攻击+10点伤害
SimaYiDecorator(Hero hero){
super(hero);
}
public double attribute1(){
double abilityPower=0;
abilityPower=hero.attribute1()+eleAttribute1();
//委托被装饰者hero调用attribute1(),然后再调用eleattribute1()
return abilityPower;
}
public double eleAttribute1(){ //装饰者新添加的方法eleAttribute1()
return PiFuAddAbilityPower;
}
@Override
public double attribute2() {
// TODO 自动生成的方法存根
return 0;
}
@Override
public double attribute3() {
// TODO 自动生成的方法存根
return 0;
}
@Override
public double attribute4() {
// TODO 自动生成的方法存根
return 0;
}
}
SimaYiDecoratorMingWen.java
package angle_decorator;
/*
角色4.2:具体装饰:铭文属性加成
*/
import angle_decorator.Hero;
import angle_decorator.Decorator;
public class SimaYiDecoratorMingWen extends Decorator{
SimaYiDecoratorMingWen(Hero hero){
super(hero);
}
public double attribute1(){
double abilityPower=0;
abilityPower=hero.attribute1()+eleAttribute1();
//委托被装饰者hero调用attribute1(),然后再调用eleattribute1()
return abilityPower;
}
public double attribute2(){
double movementSpeed=0;
movementSpeed=hero.attribute2()+eleAttribute2();
//委托被装饰者hero调用attribute2(),然后再调用eleattribute2()
movementSpeed = (double)(Math.round(movementSpeed*10)/10.0); //“四舍五入”保留小数点后1位
return movementSpeed;
}
public double attribute3(){
double AttackSpeed=0;
AttackSpeed=eleAttribute3();
return AttackSpeed;
}
public double eleAttribute1(){ //装饰者新添加的方法eleAttribute1()
double AbilityPower=10;
double mengyanAbilityPower=4.2; //1个5级铭文梦魇使得英雄法术攻击加成4.2点伤害
AbilityPower+=mengyanAbilityPower*10; //10个5级铭文梦魇的法术攻击加成
return AbilityPower;
}
public double eleAttribute2(){ //装饰者新添加的方法eleAttribute2()
double MovementSpeed=370;
double shoulieMovementSpeed=0.01; //1个5级铭文狩猎使得英雄移动速度加成1.0%
int i;
for(i=1;i<=10;i++){
MovementSpeed=MovementSpeed*(1+shoulieMovementSpeed); //累加得加成后的移速
}
//10个5级铭文狩猎的移速加成
return MovementSpeed;
}
public double eleAttribute3(){ //装饰者新添加的方法eleAttribute3()
double xinyanAttackSpeed=0.6; //1个5级铭文心眼使得英雄攻击速度加成0.6%
double shoulieAttackSpeed=1.0; //1个5级铭文狩猎使得英雄攻击速度加成1.0%
double AttackSpeed=(xinyanAttackSpeed+shoulieAttackSpeed)*10; //10个5级铭文心眼和10个5级铭文狩猎的攻速加成
return AttackSpeed;
}
@Override
public double attribute4() {
// TODO 自动生成的方法存根
return 0;
}
}
SimaYiDecoratorZhuangBei.java
package angle_decorator;
/*
角色4:具体装饰 :装备属性加成
*/
import angle_decorator.Hero;
import angle_decorator.Decorator;
public class SimaYiDecoratorZhuangBei extends Decorator{
SimaYiDecoratorZhuangBei(Hero hero){
super(hero);
}
public double attribute1(){
double abilityPower=0;
abilityPower=hero.attribute1()+eleAttribute1();
//委托被装饰者hero调用attribute1(),然后再调用eleattribute1()
return abilityPower;
}
public double attribute2(){
double movementSpeed=0;
movementSpeed=hero.attribute2()+eleAttribute2();
//委托被装饰者hero调用attribute2(),然后再调用eleattribute2()
movementSpeed = (double)(Math.round(movementSpeed*10)/10.0); //“四舍五入”保留小数点后1位
return movementSpeed;
}
public double attribute3(){
double attackSpeed=0;
attackSpeed=eleAttribute3();
return attackSpeed;
}
public double attribute4(){
double attackPower=0;
attackPower=hero.attribute4()+eleAttribute4();
//委托被装饰者hero调用attribute4(),然后再调用eleattribute4()
return attackPower;
}
public double eleAttribute1(){ //装饰者新添加的方法
double AbilityPower=52;
double wushufazhangAbilityPower=140; //巫术法杖使得英雄法术攻击加成140点伤害
double shishenzhishuAbilityPower=180; //噬神之书使得英雄法术攻击加成180点伤害
double boxuezhezhinuAbilityPower=240; //博学者之怒使得英雄法术攻击加成240点伤害
double xuwufazhangAbilityPower=240; //博学者之怒使得英雄法术攻击加成240点伤害
AbilityPower= AbilityPower+wushufazhangAbilityPower+shishenzhishuAbilityPower+boxuezhezhinuAbilityPower+xuwufazhangAbilityPower;
return AbilityPower;
}
public double eleAttribute2(){ //装饰者新添加的方法
double MovementSpeed=587.68;
double wushufazhangMovementSpeed=0.08; //巫术法杖使得英雄移动速度加成8%
MovementSpeed=MovementSpeed*(1+wushufazhangMovementSpeed);
return MovementSpeed;
}
public double eleAttribute3(){ //装饰者新添加的方法
double AttackSpeed=16;
double jisuzhanxueAttackSpeed=0.3; //极速战靴使得英雄攻击速度加成30%
AttackSpeed=AttackSpeed*(1+jisuzhanxueAttackSpeed);
return AttackSpeed;
}
public double eleAttribute4() {
double AttackPower=179;
double mingdaosimingAttackSpeed=1.0; //名刀·司命使得英雄攻击速度加成1.0%
AttackPower=AttackPower*(1+mingdaosimingAttackSpeed);
return AttackPower;
}
}
运行结果截图