美文网首页技术爱上AndroidAndroid
王者荣耀之「装饰者模式」

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

作者: 陈宇明 | 来源:发表于2017-09-03 11:05 被阅读5079次
我要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》

稳住,我们能赢!

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

相关文章

网友评论

  • 7b36c8391d80:作者,关于装饰者模式,我总觉得继承完全能实现装饰者模式,除非不让修改基类,不然感觉完全没必要。例如你本文的例子 我如果基类写成下面那样不是也可以吗,而且使用也很方便
    public abstract class 英雄 {

    private List<Buff> buffs = new ArrayList<>();

    public int 攻击(){
    return 具体攻击() + buffs.攻击();//这里buffs要遍历
    };
    public int 冷却(){
    return 具体冷却() + buffs.冷却();//这里buffs要遍历
    };

    public void addBuff(Buff buff){
    buffs.add(buff) ;
    }
    public void removeBuff(Buff buff){
    buffs.remove(buff);
    }

    public abstract int 具体攻击();
    public abstract int 具体冷却();
    ........
    }
  • 1319968cfe1a:public abstract Buff extends 英雄 {
    public abstract int 攻击()
    public abstract int 冷却()
    ........
    }
    有个疑问,这一段,不用给Buff添加额外属性了吧?既然已经继承了Hero,交给Buff的子类直接实现Hero的属性不是更好嘛?
  • 江江的大猪:装饰设计模式说白了就是组合,不过组合优于继承已经是共识了
  • 闲人逛小白:看了这篇文章,对面向对象有些懵的大脑清晰了些。😂😂,要不出一篇详细关于面向对象的文章。 @陈宇明
  • 末流丶:这里我有两个问题,这样我们怎么判断使用的英雄对象,红buff过期,我们是不是要重新实例化一个蓝buff对象?这时我们是否可以只持有一个对象?
  • 6f494c4176d3:稳住,我们能淫😀
  • 大熊小鸽鸽:希望作者您以后还能多写写设计模式,你的这种写法很容易理解。。可以考虑考虑工厂模式,观察者模式
  • 大熊小鸽鸽:只有理解了,才能更好的应用。
  • 控阁:写的不错.
  • 月亮之上:6翻了
  • 老刘爱科学:代码拖累了你
  • 抓蛙行者:可以,非常生动形象🙃顺便问下类图你用什么工具画的,感觉旁边写注视看的特别舒服
    陈宇明:@蓝士钦 http://www.jianshu.com/p/33648977d8ae
  • 流河:有时候中文命名很好用,别在意这些细节。
  • a8304ea8f57e:buff类不应该继承自英雄吧,个人感觉应该是一个属性类,因为英雄是一个对象,buff只是英雄对象的一个属性
    4d3bf4cac28c:装饰者应该和属性继承同一个接口,为了就是在外层不断的包装~
  • 86bc9928c41a:您是王者荣誉项目组成员吗?游戏引擎没这么简单吧!:flushed:
  • xXPzXj:不是应该写在数据。随时可以动态调整么?我记得很多游戏这么做的
  • 1eff7f40b465:io的包裹流
  • 巫师学徒:666666 是时候表演一波真正的技术了
  • f76f9308d391:面试官:说说你对装饰着模式的理解。
    我:我在王者荣耀中balabala
  • 铭初心:猥琐发育,别浪
  • Elta_era:去掉一个buff 怎么做?
    4d3bf4cac28c:@Elta_era 太高深了
    Elta_era:@陈宇明 先有红,后有蓝,那么先结束的应该是红。既然把装饰器比作穿衣服,那么要如何不脱外套脱衬衣呢?
    陈宇明:这个问题问的很好,我觉得可以这样每个buff都有自己的持续时间属性,到了时间就回复到上一个状态。如:无buff的李白打了红buff这时候是红buff李白,当过了红buff的时间就会把当前李白状态回复到没有被装饰的对象回到无buff李白。
  • 夜远曦白:666666,牛逼了!:+1:
  • 4fc0238b5269:貌似还是没解决buff叠加的问题:innocent:
    4fc0238b5269:@chanthuang 噢噢噢噢 看到了
    chanthuang: @名字真难取1 解决了的。套上了红buff的李白,可以再被套上一层蓝buff的。稳住,能赢。
  • b1a6bfc4cbf0:👍👍👍👍
  • Seven鑫洋:一个被代码耽误的王者
  • e18cbac0f0c0:very nice

本文标题:王者荣耀之「装饰者模式」

本文链接:https://www.haomeiwen.com/subject/kpqvrxtx.html