環(huán)信大學(xué):模型的邊界!
模型是對業(yè)務(wù)問題的抽象和解決方案。模塊是對業(yè)務(wù)問題的分解,是模型的邊界。本文基于多模塊系統(tǒng)討論,不適用于單模塊系統(tǒng)。
特定的模型只需要關(guān)注特定的業(yè)務(wù)問題,因此應(yīng)該呆在模塊內(nèi)。但是現(xiàn)實(shí)中,有時(shí)模型會(huì)穿越邊界進(jìn)入另一個(gè)模塊,并帶來問題。
假設(shè)我們在開發(fā)一個(gè)網(wǎng)上商店,首先,為了實(shí)現(xiàn)身份認(rèn)證,我們創(chuàng)建了User類,用于認(rèn)證身份,其API形如:
public?class?UserController?{????public?User?authenticate(String?username,?String?password);}
此時(shí),直接返回User已經(jīng)埋下了問題,我們繼續(xù)看。
為了讓用戶能夠買東西,我們需要向User(調(diào)用身份認(rèn)證API獲得)添加了充值和結(jié)算功能。
為了提高購買體驗(yàn),我們再次向User添加一些統(tǒng)計(jì)功能。
接下來,我們發(fā)現(xiàn)模型都是通用的依賴,將其放入一個(gè)公共模塊,稱為模型模塊給業(yè)務(wù)模塊直接使用。
隨著開發(fā),更多的功能被加到User,每次都需要修改認(rèn)證服務(wù)(User是認(rèn)證服務(wù)提供的),這很不方便,于是改為各個(gè)模塊直接訪問數(shù)據(jù)庫,并繼續(xù)添加功能直到出現(xiàn)下面的問題。
問題
問題1 修改Schema困難
當(dāng)我們需要?jiǎng)h除或者修改User的功能時(shí),我們發(fā)現(xiàn)必須先更新所有依賴模塊后才能更新,否則未更新的模塊無法存取相應(yīng)的表。然而,由于模型是一個(gè)公共模塊,我們需要查看每個(gè)業(yè)務(wù)模塊后,才能確定修改計(jì)劃。
問題2 安全隱患
每個(gè)依賴User的模塊都能看到User全部數(shù)據(jù)。這可能出現(xiàn)安全漏洞,比如,某個(gè)模塊把User的密碼打印到日志里。為此,向模型添加敏感信息時(shí),需要檢查所有依賴模塊的代碼,防止泄漏。
問題3 事故放大
模型一般都需要持久化,這些數(shù)據(jù)存儲(chǔ)在一起的,可能造成事故的放大。比如,一個(gè)模塊異常刪除了User數(shù)據(jù),那么所有使用User的功能受到到影響。
問題4 意外修改
修改模型時(shí),如果不注意本模塊是否擁有相關(guān)部分,很可能會(huì)破壞其他模塊。并且,有時(shí)候這種修改是基于條件觸發(fā)的,使得這種問題較難排查。然后,即使本模塊擁有修改的部分,也不能保證沒有其他模塊依賴。因此,修改模型時(shí),需要先分析修改范圍是否屬于本模塊,之后再查看所有模塊是否依賴現(xiàn)有實(shí)現(xiàn)。
由于以上問題,我們對模型開始只加不刪,輕易不動(dòng)已有功能...
分析
究其原因,我們發(fā)現(xiàn)根源在于認(rèn)證API返回了User。這使得模型穿越邊界變成可能(依賴認(rèn)證模塊并直接使用User)。之后,公共模塊的做法降低了穿越的難度(依賴該公共模塊)。最后,共享數(shù)據(jù)庫徹底卸下了邊界,使得模型能夠被任意模塊存取。
三步操作后,模型成了各個(gè)模塊的共享內(nèi)核,任何對內(nèi)核的改動(dòng)都會(huì)變得困難。并且這種共享內(nèi)核,如果由多個(gè)團(tuán)隊(duì)維護(hù),很可能變成沒人維護(hù)任其發(fā)展。
解決
理想的解決方案是恢復(fù)模型的邊界。每個(gè)模塊應(yīng)當(dāng)有專門的關(guān)注點(diǎn),其模型亦如此。
首先,可以逐步將User拆分到各自的模塊中。過程中如果發(fā)現(xiàn)拆不開的,有兩種辦法,如果是模塊劃分問題,可以調(diào)整模塊劃分。如果不是,則需要選擇一個(gè)模塊擁有該模型,在另一個(gè)模塊的模型中通過引用該模型ID或內(nèi)聯(lián)(復(fù)制)所需的部分。
拆分完成后,檢查提供API的地方,確保模型沒有出現(xiàn)在請求響應(yīng)中,如果有則需要更新API。
最后,消費(fèi)外部API時(shí),確保外部模型沒有直接進(jìn)入,如果有則先將其翻譯成本地模型。這一步是一種防御機(jī)制,用來防御外部API變化造成破壞。
C++
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。