王者荣耀之「装饰者模式」
2017-09-03 本文已影响5079人
陈宇明
我要buff
这样确实不需要新增类了,但是你有没有考虑到buff是可以叠加的,比如你有红buff了还可以有篮buff,这样新增一个新的buff就会新增成本的方法数,而且每次新增buff就需要修改原有的代码,这样维护真的好吗?
这样就对了,代码上起来!
这就是「装饰者模式」,在不必改变原类文件(英雄类)和使用继承的情况下,动态地扩展一个对象(李白)的功能。它是通过创建一个包装对象(buff类:红buff,篮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》」
稳住,我们能赢!
以上代码块用中文编写类名、变量名是为了让大家更好的理解,在实战过程中记得替换成相对应的英文。