前言
最近看了陳宇明老哥的英雄聯(lián)盟之「策略模式」和王者榮耀之「裝飾者模式」。作為日常上王者的我看完以后還是很驚(bu)喜(xie)的岁忘。什么辛慰?日常上王者不知道什么意思?
直接上圖:
淡定淡定.. 其實我也不想上王者的干像,都是隊友太給力了帅腌,所以每次我都帶他們躺贏 :)
好了不催牛X了,進(jìn)入本文的主題:王者榮耀之「建造者模式」
首先我們了解一下什么是建造者模式
Builder模式是一步一步創(chuàng)建一個復(fù)雜的對象的創(chuàng)建型模式麻汰,他允許用戶在不知道內(nèi)部構(gòu)建細(xì)節(jié)的情況下速客,可以更精確的控制對象的構(gòu)造流程。該模式是為了將構(gòu)建復(fù)雜對象的過程和它的部件解耦五鲫,是的構(gòu)建過程和部件的表示隔離開來溺职。
在這里我舉一個栗子,就好比王者榮耀中展示一個英雄的效果需要人物技能位喂、回城的效果和皮膚浪耘。這里就可以使用Buidler建造者模式將他們和組裝過程分離,使得構(gòu)建過程和部件都可以自由擴展塑崖,兩者之間耦合可以降到最低点待。
Builder模式的定義
將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示弃舒。
在這里為什么用Builder模式呢
1.因為他具有良好的封裝性癞埠,可以使客戶端不用知道產(chǎn)品內(nèi)部組成的細(xì)節(jié)
2.建造者獨立,容易擴展
經(jīng)典的Builder模式主要有四個參與者:
- Product:被構(gòu)造的復(fù)雜對象
- Builder:抽象接口
- ConcreteBuildr:Builder接口的具體實現(xiàn)
- Director:Builder接口的構(gòu)造者和使用者
目前來說在Android&Java開發(fā)過程中經(jīng)典的Builder模式使用的較少聋呢,一般廣泛使用的是他的一個變種苗踪,這里就不詳細(xì)的討論經(jīng)典的Builder模式了一下討論的都是變種的Builder模式。
在我們?nèi)粘i_發(fā)的過程中削锰,變種Builder模式很常見通铲。舉個栗子,在android源碼中最常用到的Builder模式就是AlertDialog.Builder器贩,使用該Builder來構(gòu)建復(fù)雜的AlerDialog對象颅夺。另一個栗子就是Glide朋截,他的底層實現(xiàn)就用到了Glide
Glide.with(this)
.load(R.raw.large_giphy_logo)
.into(giphyLogoView);
還有就是我們常用的通知,由于通知中會有很多的內(nèi)容吧黄,通過建造者模式可以很方便的來展示需要展示的內(nèi)容
上圖則是一個通知中包含了大圖標(biāo)部服、小圖標(biāo)、標(biāo)題和內(nèi)容拗慨。通知欄的內(nèi)容很豐富廓八,如下是想要構(gòu)造一些其他的內(nèi)容:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setContentTitle("標(biāo)題")//設(shè)置通知欄標(biāo)題
.setContentText("內(nèi)容") //設(shè)置通知欄顯示內(nèi)容
.setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))//設(shè)置通知欄點擊意圖
.setNumber(number) //設(shè)置通知集合的數(shù)量
.setTicker("通知到來") //通知首次出現(xiàn)在通知欄,帶上升動畫效果的
.setWhen(System.currentTimeMillis())//通知產(chǎn)生的時間赵抢,會在通知信息里顯示剧蹂,一般是系統(tǒng)獲取到的時間
.setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知優(yōu)先級
.setAutoCancel(true)//設(shè)置這個標(biāo)志當(dāng)用戶單擊面板就可以讓通知將自動取消
.set(...其他的就不舉例了)
等收到通知的時候通過mBuiler.builder來創(chuàng)建
接下來通過王者榮耀的例子帶大家熟悉一下 建造者模式
首先給沒有玩過王者榮耀的普及一下知識:
在這里我們來建造一個英雄,首先要設(shè)計這個英雄的3個技能
然后設(shè)置他的攻擊方式烦却,默認(rèn)是近戰(zhàn)攻擊
然后建造他的皮膚宠叼,不進(jìn)行建造皮膚的時候使用它的默認(rèn)皮膚,
然后是回城效果醋闭。
行了,介紹差不多了來擼碼吧朝卒。
本篇的Demo就是一個鏈?zhǔn)降慕ㄔ煺吣J降暮唵螌崿F(xiàn)证逻,首先實現(xiàn)一個引用配置類:
public class HeroConfig {
HeroBuilder mBuilder = null;
//英雄的三個技能
private String firstSkill;
private String secondSkill;
private String thirdSkill;
private String TPeffect = "無回城特效";
private String skin = "普通皮膚";
private String attack = "近戰(zhàn)攻擊";
public HeroConfig(HeroBuilder builder) {
mBuilder = builder;
init();
}
private void init() {
//這里是判斷是否構(gòu)建,未構(gòu)建用默認(rèn)值
if (mBuilder.firstSkill != null) {
firstSkill = mBuilder.firstSkill;
}
if (mBuilder.secondSkill != null) {
secondSkill = mBuilder.secondSkill;
}
if (mBuilder.thirdSkill != null) {
thirdSkill = mBuilder.thirdSkill;
}
if (mBuilder.TPeffects != null) {
TPeffect = mBuilder.TPeffects;
}
if (mBuilder.skin != null) {
skin = mBuilder.skin;
}
if (mBuilder.attack != null) {
attack = mBuilder.attack;
}
}
@Override
public String toString() {
return
"技能1——>" + firstSkill +
" 技能2——>" + secondSkill +
" 技能3——>" + thirdSkill +
" 回城特效——>" + TPeffect +
" 皮膚是——>" + skin +
" 普通攻擊屬性-->" + attack
;
}
}
在這里寫一個HeroConfig 的靜態(tài)內(nèi)部類HeroBuilder抗斤。這樣就可以實現(xiàn)HeroConfig.HeroBuilder的鏈?zhǔn)綄懛饲羝螅缦拢?/p>
HeroConfig.HeroBuilder("","","")
.builXX("")
.buildXX("")
.create();
靜態(tài)內(nèi)部類HeroBuilder 如下:
public static class HeroBuilder {
//3個技能
private String firstSkill;
private String secondSkill;
private String thirdSkill;
private String TPeffects; //回城效果
private String skin; //皮膚
private String attack; //攻擊方式
//在這里擴展一下,由于英雄的三個技能是必選的瑞眼,而回城的特效龙宏、攻擊方式和皮膚是可選的
//所以提供一個構(gòu)造方法在構(gòu)造的時候一定設(shè)置3個技能即可
public HeroBuilder(String firstSkill, String secondSkill, String thirdSkill) {
this.firstSkill = firstSkill;
this.secondSkill = secondSkill;
this.thirdSkill = thirdSkill;
}
public HeroConfig create() {
HeroConfig mHeroConfig = new HeroConfig(this);
return mHeroConfig;
}
public HeroBuilder buildAttack(String attack) {
this.attack = attack;
return this;
}
public HeroBuilder buildSkin(String skin) {
this.skin = skin;
return this;
}
public HeroBuilder buildTPeffects(String effect) {
this.TPeffects = effect;
return this;
}
}
最后在Activity中來構(gòu)建英雄:韓信、李白伤疙、后裔银酗、諸葛亮
HeroConfig 韓信=
new HeroConfig.HeroBuilder("無情沖鋒","背水一戰(zhàn)","大招!--國士無雙")
.buildSkin("白龍吟")
.create();
HeroConfig 李白=
new HeroConfig.HeroBuilder("將進(jìn)酒","神來之筆","大招!--青蓮劍歌")
.buildSkin("鳳求凰")
.create();
HeroConfig 后裔=
new HeroConfig.HeroBuilder("炙熱之風(fēng)","燎原箭雨","大招!--一支穿云箭")
.buildAttack("遠(yuǎn)程攻擊")
.buildSkin("阿爾法小隊")
.create();
HeroConfig 諸葛亮=
new HeroConfig.HeroBuilder("東風(fēng)破襲","時空穿梭","大招!--元氣彈")
.buildAttack("遠(yuǎn)程攻擊")
.create();
HeroConfig 土豪諸葛亮=
new HeroConfig.HeroBuilder("東風(fēng)破襲","時空穿梭","大招!--元氣彈")
.buildSkin("黃金分割率")
.buildTPeffects("愛心回城特效")
.buildAttack("遠(yuǎn)程攻擊")
.create();
Log.e("韓信", 韓信.toString());
Log.e("李白", 李白.toString());
Log.e("后裔", 后裔.toString());
Log.e("諸葛亮", 諸葛亮.toString());
Log.e("土豪諸葛亮", 土豪諸葛亮.toString());
最后打印的結(jié)果如下:
總結(jié)
好了這就是變種Builder模式,在Android開發(fā)比較常用徒像,通常作為配置類的構(gòu)建器將配置的構(gòu)建和表示分離黍特,也就是王者榮耀中的各種技能、特效等锯蛀,將他們從目標(biāo)類中隔離出來避免過多的setter方法灭衷。通過鏈?zhǔn)綄崿F(xiàn)使得代碼更簡潔、易懂旁涤。缺點呢就是會產(chǎn)生多余的Builder對象消耗內(nèi)存翔曲,不過這個缺點可以被他的優(yōu)點所彌補迫像。變種的Builder模式是根據(jù)經(jīng)典的Builder模式在日常開發(fā)中的需要延伸出來的一種方式,經(jīng)典Builder模式UML如下:
現(xiàn)在在日常的開發(fā)中Director角色經(jīng)常會被忽略瞳遍,這樣會相對的減少了構(gòu)造的步驟而直接使用一個Builder來進(jìn)行對象的組裝闻妓,最關(guān)鍵的還是Builder通常為鏈?zhǔn)秸{(diào)用,它的每個setter方法都返回自身傅蹂,也就是代碼中的return this
,這樣就可以實現(xiàn)鏈?zhǔn)秸{(diào)用了纷闺。
最后
本篇的這波操作還可以吧,我覺得可以份蝴,本來是準(zhǔn)備上傳一段諸葛秀操作的視頻給大家壓壓驚犁功,結(jié)果第一把保存視頻以后不能導(dǎo)出,第二把開了英雄時刻手機沒有內(nèi)存沒保存下來... 干脆不錄了婚夫,想來躺的可以一起農(nóng)藥哇~~ 最后只留下了2把戰(zhàn)績給大家了浸卦。。
如果喜歡本文的話案糙,歡迎點擊一下 “喜歡” 給予鼓勵支持!