優(yōu)化解耦的設(shè)計思考
基于開源項目進行開發(fā)已經(jīng)越來越普遍,WebKit和Android都有很多的深度定制的版本。
對這樣龐大工程修改的邏輯越來越多,日后想要同步升級就要面對更大的復雜性和風險。跟隨開源項目同步升級,尋求上層的創(chuàng)新和優(yōu)化才比較適合未來的產(chǎn)品開發(fā)策略。深度定制的方式會遭遇越來越多的尷尬。
修改是必要的,但如何最大化地降低耦合和隔離對原生代碼邏輯的修改?邏輯碎片的風險也許大家都體會過。以下是我對一個問題的思考,與大家分享,拋磚引玉。
1. 問題定義
首先交待一下當前的狀況。
1.有對WebKit原生內(nèi)核中HTMLMediaElement修改的需求。
由于實現(xiàn)的限制,導致了必須對HTMLMediaElement進行修改。
2. 不同平臺的修改邏輯混雜在一起。
在不同平臺上的適配內(nèi)容也不盡相同,所以其中有許多使用宏來區(qū)分系統(tǒng)的修改。
問題就是有沒有可能將這些修改的實現(xiàn)放到獨立的文件中去,在HTMLMediaElement中只做少量的修改,最大化的減少對原生代碼的修改?或者是有規(guī)則的修改??傊阌诤妥钚碌腤ebKit代碼同步。
2. 問題分析
首先從設(shè)計上來看這個問題,可以將WebKit的實現(xiàn)視為核心邏輯,將我們的修改視為一個輔助邏輯或特殊邏輯。
這樣就可以有一個設(shè)計上問題定義:把這部分邏輯從主邏輯中抽離的設(shè)計方法,但不改變原來的類的層次架構(gòu)。
繼承并不合適。因為一部分HTMLMediaElement中的成員定義為protected,它本身已經(jīng)被HTMLAudioElement和HTMLVideoElement所繼承。還有對應(yīng)的Render、JS Binding與它的對應(yīng)問題。遠不是在parser位置將video和audio對應(yīng)的類改成新類就可以的, 而是需要更改到HTMLMediaElement的定義。
解決方案就是提供一個Helper類,如MediaElementHelper來處理特殊邏輯。
2. 實現(xiàn)說明
2.1 建構(gòu)
在HTMLMediaElement的建構(gòu)函數(shù)中加入:
m_helper = MediaElementHelper::create(this);
不同平臺可以使用相同的類定義,但實現(xiàn)不同。
2.2 相互調(diào)用
helper又為HTMLMediaElement的友類,就可以訪問HTMLMediaElement的私有變量,或者執(zhí)行私有成員函數(shù)。如果認為這樣風險高,也可以像下面這樣專為helper增加一些訪問私有成員的接口。
這樣在需要進行特殊邏輯判斷和處理的地方,就使用m_helper來調(diào)用執(zhí)行。具體的行為則在不同的helper類中實現(xiàn)。
3. 評估
關(guān)于helper的使用一直是有爭議,網(wǎng)上也有很多避免使用helperclass的討論。主要論調(diào)在于認為helper class是過程化的產(chǎn)物,思考時是考慮的是流程上的邏輯補充。雖然在目前場景下,這也算是一個解決方案,但不是最佳方案,因為這些做同樣增加了設(shè)計的復雜性。