screeps 模塊化方案

作為一個(gè)編程相關(guān)的游戲,自然少不了造輪子和用輪子,這幾年也接觸了很多廣為流傳的輪子和框架,其中不乏一些擁有“革命性”理念的設(shè)計(jì),我也從中吸取了許多的經(jīng)驗(yàn)。但是大家可以發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象:廣為流傳的輪子大多相當(dāng)基礎(chǔ)

我們經(jīng)??梢哉业揭恍┗A(chǔ)的輪子:例如布局規(guī)劃、尋路、建筑緩存等,但是對(duì)于高級(jí)輪子,例如 lab 合成,factory 合成,乃至更高級(jí)的戰(zhàn)爭模塊,無一例外都找不到可以用的輪子。這朵烏云一直徘徊在 screeps 的大廈上,很大程度的破壞了那些想要把精力聚焦到某個(gè)具體模塊的玩家體驗(yàn)。

接下來,我們就分析一下為什么會(huì)這樣,以及如何解決這個(gè)問題,讓大家可以從只能各自為戰(zhàn)的泥潭中脫身出來。

為什么沒有出現(xiàn)高級(jí)輪子?

問題的根源跟簡單:越高級(jí)的模塊的依賴就越多。我有一個(gè) factory 模塊,它想要工作的話需要一個(gè)物流模塊、一個(gè)跨房資源共享模塊,一個(gè) power 管理模塊等等...一堆模塊相互依賴,大家共同組成了一個(gè)不斷蠕動(dòng)的肉球,其中相互依賴的血管盤根錯(cuò)節(jié)看不清楚,想要把工廠模塊單獨(dú)拿出來給其他人用?洗洗睡吧您。

這里可以套用 JoeArmstrong 的那句話:

你想要個(gè)香蕉,但拿到的卻是拿著香蕉的猩猩,乃至最后你擁有了整片叢林。

你想復(fù)用一個(gè) lab 模塊,但是你需要同時(shí)把房間物流模塊也一塊裝進(jìn)來,層層嵌套之后,你發(fā)現(xiàn)幾乎把原來項(xiàng)目一半的代碼都搞了過來。隨著模塊的層級(jí)越高,你需要引入的依賴模塊就越多。并且你還要避免新引入的猩猩和原來自己寫的猩猩打架。

怎么解決?避免直接依賴

現(xiàn)在我們知道了問題的根源,那想解決這個(gè)問題也很簡單:把模塊之間的依賴關(guān)系刪了不就好了

// 就是這種引入代碼,不可以出現(xiàn)在工廠模塊里
import { getGlobalResourceShare } from 'src/module/resourceShare'

說得輕巧,刪?怎么刪,工廠模塊就是需要物流模塊啊,你不讓我寫引入,那我咋搞,嘴里含根內(nèi)存條靠腦補(bǔ)?

你說的沒錯(cuò),依賴關(guān)系不可以被消除,但是可以被轉(zhuǎn)移。我們只是不想讓他出現(xiàn)在模塊內(nèi)部,只要能想辦法把這些引入代碼搞出去就可以了。

首先看一下我們?cè)镜脑O(shè)計(jì),每個(gè)模塊相互獨(dú)立并調(diào)用其他模塊的接口完成自己的功能,因?yàn)楸舜酥g牽一發(fā)而動(dòng)全身的依賴關(guān)系,導(dǎo)致了我們無法單獨(dú)復(fù)用某個(gè)模塊:

但是如果我們通過某種方式“隔離”了其他的接口,讓本模塊調(diào)用的“外部模塊操作”是這個(gè)隔離層上暴露的接口,這樣模塊內(nèi)部的實(shí)現(xiàn)就只依賴于這個(gè)隔離層,從而保證模塊 內(nèi)部 的純潔性。

然后,我們就可以通過在“提供”和“依賴”之間相互傳遞,來實(shí)現(xiàn)模塊之間的相互協(xié)作。

這時(shí)候我們可以發(fā)現(xiàn),所有“臟亂差”的依賴關(guān)系從模塊之間沉淀到了一起,由于在這一層里 所有的代碼都是為了讓不同模塊彼此合作。為了方便稱呼,我們就可以他稱之為“膠水層”或正式一點(diǎn)的“組合層”。

至此,我們就把整個(gè)應(yīng)用分為干凈的“模塊層”和干臟活的“膠水層”。可以看到,原來那些依賴關(guān)系依舊存在,但是從 模塊與模塊之間 轉(zhuǎn)移到了 模塊之外。

現(xiàn)在,我們就可以簡單的把某個(gè)模塊拿出來、替換成新的模塊,然后修改一下膠水層里的依賴關(guān)系就可以了。整個(gè)替換過程里完全不需要侵入到其他模塊內(nèi)部。

我們可以把每個(gè)功能模塊想象成電腦里的內(nèi)存、電源、硬盤、顯卡。我們要開發(fā)的 screeps bot 就像是在組裝一臺(tái)電腦,每個(gè)模塊都不能單獨(dú)工作,但是他們都提供了各種接口和插槽,我們只需要按照說明書把他們用各種線纜連接在一起,電腦就能正常工作了!

這里的各種線纜和插口就是上文中提到的“膠水層”,想更換一個(gè)顯卡,只需要把與之相關(guān)的插口檢查一遍就行,不用把 CPU 開蓋或者在主板上搞什么飛線(不用侵入其他模塊進(jìn)行修改)。

小結(jié)

本篇文章里,我們介紹了為什么沒辦法進(jìn)行高級(jí)輪子的復(fù)用,以及提出了一個(gè)方案來嘗試解決這個(gè)問題:通過給每個(gè)模塊設(shè)定好外部依賴的接口,讓模塊對(duì)其他模塊的依賴轉(zhuǎn)移成對(duì)自己接口的依賴,從而保證模塊內(nèi)部和其他模塊是相互隔離的。

這里我們需要明確一個(gè)觀點(diǎn),不需要任何配置,即插即用的高級(jí)輪子是不存在的。越高級(jí)的輪子依賴的東西就越多,當(dāng)我們想要獨(dú)立一個(gè)輪子時(shí),這些依賴關(guān)系必定會(huì)暴露出來,不提供這些依賴,那你就用不了這個(gè)輪子,這和“不需要任何配置”是相違背的。

其實(shí)上面的設(shè)計(jì)給你倆小時(shí)你也想得出來。關(guān)鍵就是如何將其落實(shí)到代碼上面。這一部分內(nèi)容我們會(huì)在 下篇文章 里詳細(xì)介紹,不用擔(dān)心,非常簡單。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容