大话设计模式の王者荣耀英雄设计
内容目录
一、你的大脑在想什么
大部分学习是一件充满乏味和反人性(克服懒惰)的事(i薙鱼导师:琦大大),假如野人我们的祖先不学会使用火和工具,那么可能就没有现在的我们了,一切都是为了部落,为了生存。[FollowMe]我会尽力使学习过程变得比较轻松愉悦。设计模式是前辈们总结的经验和智慧,就好比武林绝学葵花宝典(还不需要你自宫,简直不要太棒!)
1.1 谁适合读这篇文章
√你懂Java么?(不求精通,会就行了);
√你想学习,了解,记得并应用设计模式,以及其所基于00设计原则么?;
√你是不是更喜欢一种轻松的氛围,就像在餐桌上交谈一样,而不愿意被动地听技术报告似的枯燥乏味的说教?
1.2 大脑记忆是如何工作的
有些事情只发生了一次但是你记得十分清楚,比如游泳差点淹死、被人打、被人羞辱或是很尴尬的瞬间等等,这时大脑会强化记忆“这[TM]太重要了,下次一定不能让这种事情发生了”。
亦或是表白成功、走上了人巅峰,这时大脑也会强化记忆“这么高光的时刻,太重要了,我要好好记住”。
还有反复多次的去背单词,十遍二十遍,最终你记住了。大脑被动记忆“既然出现这么多次,那一定很重要吧,我就勉为其难的记住它了”
而我所要做的就是尽我所能让你的大脑兴奋起来,这样你就会对所学的设计模式知识印象更为深刻,理解更加透彻here we go

二、欢迎来到王者荣耀之英雄设计
2.1 设计英雄

2.2 新英雄设计(远古版本)
技术总监罗工:“最近我们要出一款新英雄,辅助孙膑,模型已经设计好了,你们把底层代码写写吧!”,研发鱼:“ok,收到!”,然后薙鱼下去开始兴奋的写起了代码,灵光一闪想起来孙膑不是被膑足(夏商五刑之一,又称刖刑,是断足或砍去犯人膝盖骨的刑罚)了么,他不可能走路的耶,所以一定是得用飘的,哈哈,机智如我,开干。

2.3 翌日(第二天)
游戏测试小z发了一篇测试报告和录频到研发的群里@薙鱼,整个群里炸开了锅,天哪所有的英雄的都飞了起来。薙鱼顿时吓得目瞪口呆,这时罗工冲冲的走了过来,你丫的干啥呢,猪八戒都上天了你知道么!薙鱼方才缓过神来,小声嘟囔了一句:“八戒会飞的呀”。

说归说,闹归闹,别拿代码(饭碗)开玩笑,嘿嘿,这就去改喽。
2.4 马总发言
马总笑口颜开的说到:“咱们公司这个王者荣耀啊,做的非常棒,为公司带来巨大的收益,在座各位都辛苦啦!你们年底年终奖翻倍”(啪啪啪…掌声雷动)。不过呢最近有位粉丝在微博@我说:“马爸爸,我今年12岁,很喜欢你们公司的王者荣耀这款游戏,但是每次回城的时候让我很失望”,我问他说:“为什么呀?,他说虽然我皮肤都是荣耀典藏的,但是回城的时候嗖的一下就会回去了,而且所有英雄都一样,毫无创意和体验感,完全不能将我和那些白嫖党分别开,我不快乐”。你们都懂了么?。话音刚落底下异口同声的答到:“我们知道了,马总!”,啪啪啪…掌声停,会议散。

从上面不难看出继承会导致一些不好影响:
- 运行时的行为不容易改变
- 改变会牵一发动全身,引起大麻烦
- 很难知道英雄的全部行为,比如新出的英雄澜,会走walk还会游泳swim
2.5 一般接口方式

这样看似时解决了问题,但随之而来的是:
- 直接继承接口无法达到代码复用的效果
- 修改某一个行为时,必须往下追踪,并在每一个定义此行为的类中修改它,一不小心就会造成新的错误
2.6 针对接口编程,而不针对实现

这样的设计,可以让飞行和回城动作被其它对象复用,因为这些行为已经和英雄类无关了。而我们可以新增一些行为,不会影响到既有的行为类,也不会影响到使用到飞行行为的英雄。
2.7 英雄的行为
我们用两个相似的方法performMove()和performRecall()取代Hero类中的move()和recall()方法,
英雄不在亲自处理移动行为和回城行为了,而是委托给moveBehavior和recallBehavior处理,move()和recall()直接从moveBehavior和recallBehavior接口对象中调用

三、开始撸代码
3.1 移动方式
/**
* 移动行为
* @author ITyushuo
*
*/
public interface MoveBehavior {
void move();
}
/**
* 游泳
* @author ITyushuo
*
*/
public class Swim implements MoveBehavior {
@Override
public void move() {
System.out.println("峡谷河道游泳");
}
}
/**
* 行走
* @author ITyushuo
*
*/
public class Walk implements MoveBehavior {
@Override
public void move() {
System.out.println("峡谷间行走");
}
}
/**
* 飞行
* @author ITyushuo
*
*/
public class Fly implements MoveBehavior {
@Override
public void move() {
System.out.println("峡谷间飞来飞去");
}
}
3.2 回城动作
/**
* 回城行为
* @author ITyushuo
*
*/
public interface RecallBehavior {
void recall();
}
/**
* 站立回城
* @author ITyushuo
*
*/
public class StandUp implements RecallBehavior {
@Override
public void recall() {
System.out.println("原皮白嫖党,站立回城");
}
}
/**
* 时空穿梭
* @author ITyushuo
*
*/
public class Shuttle implements RecallBehavior {
@Override
public void recall() {
System.out.println("时空穿梭回城啦!");
}
}
3.3 英雄抽象类
/**
* 英雄
* @author ITyushuo
*
*/
public abstract class Hero {
MoveBehavior moveBehavior;
RecallBehavior recallBehavior;
public int level;
/**
* 被动技能
*/
public abstract void passiveSkill();
/**
* 移动
*/
public void performMove() {
moveBehavior.move();
}
/**
* 回城
*/
public void performRecall() {
recallBehavior.recall();
}
/**
* 升级+点(升一级)
*
*/
public void upgrade() {
if (level >= 15) {
System.out.println("已经是最高等级,不能再升级");
return;
}
level++;
System.out.println("升级为:"+level+"级");
}
public void setMoveBehavior(MoveBehavior moveBehavior) {
this.moveBehavior = moveBehavior;
}
public void setRecallBehavior(RecallBehavior recallBehavior) {
this.recallBehavior = recallBehavior;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
/**
* 狄仁杰
* @author ITyushuo
*
*/
public class Direnjie extends Hero {
public final static String HERO_NAME = "英雄:狄仁杰(超时空战士)";
@Override
public void passiveSkill() {
System.out.println("迅捷:每次普攻获得一层迅捷效果,每层迅捷效果增加6%攻速和5%移速,最多叠5层");
}
}
/**
* 孙膑
* @author ITyushuo
*
*/
public class Sunbin extends Hero {
public final static String HERO_NAME = "英雄:孙膑";
@Override
public void passiveSkill() {
System.out.println("时间沙漏:释放技能会提高30%的移动速度,持续两秒");
}
}
/**
* 澜
* @author ITyushuo
*
*/
public class Lan extends Hero {
public final static String HERO_NAME = "英雄:澜";
@Override
public void passiveSkill() {
System.out.println("猎杀:但生命值低于30%,会被澜视作“猎物”,澜对猎物将会额外造成10%的伤害");
}
}
3.4 召唤师峡谷测试
/**
* 召唤师峡谷测试
* @author ITyushuo
*
*/
public class SummonersCanyonTest {
public static void main(String[] args) {
MoveBehavior walk = new Walk();
RecallBehavior shuttle = new Shuttle();//穿越时空虫洞
Hero direnjie = new Direnjie(); //创建英雄
System.out.println(Direnjie.HERO_NAME); //打印英雄名
direnjie.setMoveBehavior(walk);//设置移动行为
direnjie.setRecallBehavior(shuttle);//设置回城动作
direnjie.setLevel(15);//设置英雄等级
direnjie.upgrade();//召唤师加点升一级
direnjie.performMove();//移动
direnjie.performRecall();//回城
System.out.println("----------------");
MoveBehavior swim = new Swim();//游泳移动
RecallBehavior standUp = new StandUp();//站立回城
Hero lan = new Lan();
System.out.println(Lan.HERO_NAME);
lan.setMoveBehavior(swim);
lan.setRecallBehavior(standUp);
lan.setLevel(4);
lan.upgrade();//升一级
lan.performMove();
lan.setMoveBehavior(walk);
System.out.println("一技能效果消失或游出河道时:");
lan.performMove();
lan.performRecall();
System.out.println("----------------");
MoveBehavior fly = new Fly();//飞行移动
Hero sunbin = new Sunbin();
System.out.println(Sunbin.HERO_NAME);
sunbin.setMoveBehavior(fly);
sunbin.setRecallBehavior(standUp);
sunbin.setLevel(1);
sunbin.upgrade();//升一级
sunbin.performMove();
sunbin.performRecall();
}
}
3.5 测试结果
英雄:狄仁杰(超时空战士)
已经是最高等级,不能再升级
峡谷间行走
时空穿梭回城啦!
英雄:澜
升级为:5级
峡谷河道游泳
一技能效果消失或游出河道时:
峡谷间行走
原皮白嫖党,站立回城
英雄:孙膑
升级为:2级
峡谷间飞来飞去
原皮白嫖党,站立回城
四、00原则
- 封装变化
- 多用组合,少用继承
- 针对接口编程,不针对实现编程
- 为交互对象之间的松耦合而不懈努力
本文参考来源
书籍:HeadFirst设计模式
23种设计模式:http://c.biancheng.net/design_pattern/
如果觉得本文对你或你的小伙伴有所帮助,可以帮我推荐转发,希望能帮助更多像我一样喜欢这种扯淡式学习的IT人。你们的支持是我前进的动力。
我是i薙🐟一只会敲bug的挨踢(IT)鱼下篇再会


浙公网安备 33010602011771号