×

王者荣耀之「装饰者模式」

96
陈宇明
2017.09.03 11:05* 字数 650
我要buff

前言

之前写过一篇英雄联盟之「策略模式」,居然有人说没玩过,那么今天给大家带来一篇王者荣耀篇,如果还没玩过,那就去玩玩,毕竟学习是需要付出成本的!

问答环节

在王者荣耀中buff对于整场比赛起着至关重要的作用,那么如果用OO思想来设计这些buff?

小明:简单,继承原来的英雄类加个buff属性就好了。

厉害了,我的明,看到你这多类,我心好累!你这还是一个英雄,那么多个英雄就多少个类?还有如果游戏再新增一个黄buff呢?那你又要新增多少个不同的buff类?

小明:你这么一说,好像确实不对劲,虽然是copy代码,但是作为准高级工程师的我来说还是需要改进的。这样吧我在所有英雄的基类新增buff属性好了,这样一来就一劳永逸了,完美的解决了你上面提到的2个问题,无论多少英雄,无论多少buff,从此再也不要新增类了。是不是很强势?快夸我!


这样确实不需要新增类了,但是你有没有考虑到buff是可以叠加的,比如你有红buff了还可以有篮buff,这样新增一个新的buff就会新增成本的方法数,而且每次新增buff就需要修改原有的代码,这样维护真的好吗?

开闭原则:类应该对扩展开发,对修改关闭。

小明:那可怎么办呀?这也不行,那也不行!

给你个提示吧,上次我们提到了一个设计原则:多用组合,少用继承。你往这方面想想,别脑子里只有继承。

小明:我知道了,其实可以新建一个“装饰类”,把 红buff,篮buff,龙buff,可以看成一件衣服,需要的时候就用相应的衣服穿上去给相应的英雄,这样一来新增一个buff我只需要新增一个类就好了,并且不需要修改原有的代码。

李白:还有谁?

这样就对了,代码上起来!

代码环节

抽象父类

public abstract class 英雄 {
  public abstract int 攻击()
  public abstract int 冷却()
   ........
}

实现英雄的李白。

public class 李白 extends 英雄 {
   @Override
   public int 冷却(){
      return 5;
  }
   ........
}

Buff抽象类

public abstract Buff extends 英雄 {
   public abstract int 攻击()
  public abstract int 冷却()
   ........
}

不同Buff的实现类。

public 红buff extends Buff {

   private 英雄 英雄;
   public 红buff(英雄 英雄){
        this.英雄 = 英雄;
    }
     @Override
   public int 攻击() {
     return 英雄.攻击() + 红buff额外攻击;
   }
   .........
 
}
public 蓝buff extends Buff {

   private 英雄 英雄;
   public 蓝buff(英雄 英雄){
        this.英雄 = 英雄;
    }

    @Override
   public int 冷却() {
     return 英雄.冷却()  + 篮buff额外减少的冷却值;
   }
   .........

}

客户端

public class Client {
    public static void main(String[] args) {
        // 没有buff的英雄
        英雄 无buff李白 = new 李白();
       
        // 打了红
        红buff 红buff李白 = new 红buff(无buff李白);

        // 再来个篮
        篮buff 红蓝buff李白 = new 篮buff(红buff李白);

    }
}

总结

《Head first 设计模式》

这就是「装饰者模式」,在不必改变原类文件(英雄类)和使用继承的情况下,动态地扩展一个对象(李白)的功能。它是通过创建一个包装对象(buff类:红buff,篮buff, ...),也就是装饰来包裹真实的对象。

最后为了让大家感受下BUFF对于整场比赛起着重要性,送上「王者荣耀 鬼畜神曲《我拿BUFF》

稳住,我们能赢!

以上代码块用中文编写类名、变量名是为了让大家更好的理解,在实战过程中记得替换成相对应的英文。

Android
Web note ad 1