變更孤島
1 定義
變更孤島爽蝴,是一種創(chuàng)建可演化的架構(gòu)的模式沐批。其主旨是將大型系統(tǒng)分割成多個獨立可替換的部分纫骑,這些可替換的部分在之后的架構(gòu)演化中逐步替代以適合的架構(gòu)形態(tài),針對可替代性而不是可重用性設(shè)計九孩。
2 上下文和問題
在構(gòu)建系統(tǒng)的時候先馆,不一定從一開始就能設(shè)計出合適的架構(gòu)。此時需要先構(gòu)建一個初始的架構(gòu)躺彬,并使其能隨對系統(tǒng)理解的加深而逐步進行演化煤墙。
3 解決方案
對于上述可演化的架構(gòu),存在一種構(gòu)建方法宪拥,使用此方法構(gòu)建的架構(gòu)具有適應(yīng)性仿野,能夠在特定的時間點轉(zhuǎn)換為合設(shè)的架構(gòu)。這種構(gòu)建方法需要遵循以下的原則:
將大型的系統(tǒng)分割成“變更孤島”
針對可替代性進行設(shè)計她君,而不是可重用性
最小化共享依賴脚作,重點關(guān)注自治和冗余,而不是重用
先將系統(tǒng)按變更作用的范圍進行大粒度的劃分缔刹,劃分出的各個部分的變更僅影響系統(tǒng)內(nèi)部球涛,而不會影響彼此。此時劃分的部分稱為“變更孤島”校镐。之后的架構(gòu)演進亿扁,圍繞替換這些變更孤島,而不是重用或者重構(gòu)這些變更孤島來進行鸟廓。即設(shè)計出提供某個孤島相同能力的子系統(tǒng)時魏烫,對此孤島進行替換。
而對于子系統(tǒng)肝箱,也可采用這種方式進一步進行變更孤島的劃分哄褒、替換,直到系統(tǒng)的架構(gòu)全部清晰煌张。
由于劃分的孤島彼此耦合很小呐赡,功能內(nèi)聚,可到達最小化共享依賴的目的骏融。因此對孤島進行冗余链嘀、替代都非常容易。這樣可方便的對某個孤島的架構(gòu)和實現(xiàn)進行實驗档玻,一旦失敗也可以方便的回退到原架構(gòu)怀泊。
比如,在服務(wù)的劃分中误趴,經(jīng)常會劃分成前端服務(wù)霹琼、業(yè)務(wù)邏輯服務(wù)和數(shù)據(jù)服務(wù),它們之間的調(diào)用關(guān)系如下:
前端服務(wù)、業(yè)務(wù)邏輯服務(wù)枣申、數(shù)據(jù)服務(wù)都是功能內(nèi)聚的部分售葡,可作為變更孤島,即他們內(nèi)部的變更在內(nèi)部消化忠藤,不影響到使用方挟伙。但如果直接按調(diào)用關(guān)系組織這些服務(wù),是無法達到變更孤島的架構(gòu)目標(biāo)的模孩,因為前端服務(wù)使用了業(yè)務(wù)邏輯服務(wù)尖阔,會受業(yè)務(wù)邏輯服務(wù)變更的影響;而業(yè)務(wù)邏輯服務(wù)使用了數(shù)據(jù)服務(wù)榨咐,又會受數(shù)據(jù)服務(wù)變更的影響介却。這種架構(gòu)是無法實現(xiàn)不同“孤島”間的松耦合的。
從長期來看祭芦,業(yè)務(wù)邏輯的變化比數(shù)據(jù)存儲技術(shù)和前端技術(shù)的變化慢得多筷笨,依賴應(yīng)向著更穩(wěn)定的方向憔鬼,因此前端服務(wù)和數(shù)據(jù)服務(wù)依賴業(yè)務(wù)邏輯服務(wù)是合理的龟劲。而數(shù)據(jù)服務(wù)、前端服務(wù)應(yīng)該是能隨需求的變化或技術(shù)的迭代轴或,快速變更的昌跌。這樣,我們通過依賴反轉(zhuǎn)方法照雁,將業(yè)務(wù)邏輯服務(wù)對數(shù)據(jù)服務(wù)的依賴關(guān)系反向蚕愤。如下圖:
按這種方式進行調(diào)整之后,業(yè)務(wù)邏輯服務(wù)只依賴抽象的數(shù)據(jù)接口饺蚊,而不再依賴具體的數(shù)據(jù)服務(wù)了萍诱。而數(shù)據(jù)服務(wù)只要實現(xiàn)數(shù)據(jù)接口,無論內(nèi)部怎樣變更污呼,替換成哪種實現(xiàn)技術(shù)裕坊,都可以支撐業(yè)務(wù)邏輯服務(wù),并且這種變化不會被業(yè)務(wù)邏輯服務(wù)感知燕酷。
而業(yè)務(wù)邏輯服務(wù)只要對前端服務(wù)提供的接口不變籍凝,也可以有效的對前端服務(wù)屏蔽變化。這樣苗缩,前端服務(wù)饵蒂、業(yè)務(wù)邏輯服務(wù)、數(shù)據(jù)服務(wù)就能達成變更孤島的架構(gòu)目標(biāo)了酱讶。
下面擴展一下業(yè)務(wù)邏輯服務(wù)和數(shù)據(jù)服務(wù)之間的關(guān)系退盯。在實際的系統(tǒng)設(shè)計中,經(jīng)常出現(xiàn)多個業(yè)務(wù)邏輯服務(wù)都使用數(shù)據(jù)服務(wù)的情形,直接的調(diào)用關(guān)系如下圖:
這種架構(gòu)中得问,數(shù)據(jù)服務(wù)被業(yè)務(wù)服務(wù)A和B重用(共享)囤攀,但卻使業(yè)務(wù)服務(wù)A、業(yè)務(wù)服務(wù)B和數(shù)據(jù)服務(wù)產(chǎn)生了強耦合:不但讓業(yè)務(wù)服務(wù)A宫纬、業(yè)務(wù)服務(wù)B都感知了數(shù)據(jù)服務(wù)的變化焚挠,而且從業(yè)務(wù)服務(wù)A出發(fā)產(chǎn)生的數(shù)據(jù)服務(wù)變更也會被業(yè)務(wù)服務(wù)B感知,業(yè)務(wù)服務(wù)B不得不因為業(yè)務(wù)服務(wù)A的變更而變更漓骚。
從架構(gòu)層面來看蝌衔,對服務(wù)的重用越多,服務(wù)間的耦合就會越重蝌蹂。重用并非服務(wù)間良好的組織方式噩斟。如果從變更孤島的思路來思考,業(yè)務(wù)服務(wù)A和業(yè)務(wù)服務(wù)B看數(shù)據(jù)服務(wù)孤个,都應(yīng)該是可替換的剃允。可以采用依賴反轉(zhuǎn)將重用使用關(guān)系改變齐鲤。如下圖:
在這種關(guān)系下斥废,業(yè)務(wù)服務(wù)A和業(yè)務(wù)服務(wù)B都不再依賴數(shù)據(jù)服務(wù),而是依賴彼此定義的抽象數(shù)據(jù)接口给郊。數(shù)據(jù)服務(wù)的變更可封閉在數(shù)據(jù)服務(wù)內(nèi)部牡肉。而且,可以為業(yè)務(wù)服務(wù)A和業(yè)務(wù)服務(wù)B使用不同的數(shù)據(jù)服務(wù)實現(xiàn)淆九,增強了系統(tǒng)的擴展性统锤。這就是針對替代性而不是可重用性進行設(shè)計的意義所在。如下圖:
4 優(yōu)點
架構(gòu)中的部件功能內(nèi)聚炭庙,彼此松耦合饲窿,可逐步演進;
系統(tǒng)各個部分可方便的替換焕蹄、回退逾雄,利于實驗性特性的實現(xiàn),比如A/B測試擦盾;
復(fù)雜系統(tǒng)架構(gòu)演進時嘲驾,可劃分成多個變更孤島各自進行架構(gòu)演進。由于孤島之間互不干擾迹卢,因此系統(tǒng)演進可從容地分階段辽故、分層次地開展。
由于孤島可替代腐碱,而不是被依賴誊垢,這種架構(gòu)符合依賴倒置原則(DIP)掉弛,有利于將具體技術(shù)決策延后,增強架構(gòu)對變化的適應(yīng)性喂走。
5 問題和注意事項
一開始的劃分不宜粒度太細殃饿。孤島的劃分時,優(yōu)先從現(xiàn)有功能可替代角度思考芋肠。避免一開始就被架構(gòu)是否優(yōu)美乎芳、部件如何共享如何重用等無關(guān)功能解耦的問題束縛住手腳。
6 應(yīng)用場景
對大型系統(tǒng)進行微服務(wù)劃分帖池,但初期無法完全理解系統(tǒng)奈惑,不能細粒度的劃分微服務(wù)時;
將現(xiàn)有大型系統(tǒng)遷移至微服務(wù)架構(gòu)睡汹,存在某些因素?zé)o法判斷微服務(wù)拆分是否合理時肴甸,可采用這種可演化的架構(gòu)方式;