好的代碼
要說清楚DSL能帶來什么,先要理解需要什么。一份好的代碼咏瑟,應(yīng)該滿足下述屬性(重要程度遞減) :
1.正確
它需要實現(xiàn)當(dāng)前所需的功能拂到,可以正常工作。
2.可擴(kuò)展
對于新的需求码泞,代碼應(yīng)該容易擴(kuò)展兄旬,它的變動成本應(yīng)該盡量小:這個成本應(yīng)該包括設(shè)計、編碼余寥、測試领铐、故障修復(fù)等全流程的成本;
可以想象后端的成本往往比前端要大,特別是缺乏良好設(shè)計的情況下宋舷。一般資源前移绪撵,投入更多的資源在設(shè)計、編碼上祝蝠,是合適的策略音诈。特別是對于注定的大型項目更是如此。但對于前端的投入需要有明確的實施或評判標(biāo)準(zhǔn)绎狭。
3.可讀
可讀和可擴(kuò)展看似會有沖突细溅。想要維護(hù)高度抽象、有良好分層結(jié)構(gòu)的代碼一定需要付出相應(yīng)的學(xué)習(xí)成本儡嘶。它不會那么”好讀”喇聊。即便沖突,也應(yīng)該首先保證擴(kuò)展性蹦狂。
保證擴(kuò)展性的情況下誓篱,代碼結(jié)構(gòu)應(yīng)該良好的組織結(jié)構(gòu),命名應(yīng)該更加準(zhǔn)確凯楔,以便于理解燕鸽。長遠(yuǎn)的看可擴(kuò)展性和可讀性并不沖突,缺乏抽象的代碼既不會好讀更不會容易擴(kuò)展啼辣。
4.沒有多余的部分
不要實現(xiàn)那些還沒有發(fā)生的需求啊研。
如果通過對領(lǐng)域知識的了解,你已經(jīng)知道某些變化方向一定會發(fā)生鸥拧,只是這幾天或者這個版本還不需要實現(xiàn)這些功能党远。那么就需要提前考慮這些變化方向,避免后續(xù)推倒重寫富弦。特別是沟娱,對于架構(gòu)師來說,決不可能也不應(yīng)該對系統(tǒng)的變動和演進(jìn)一無所知腕柜。
這一點描述的實際上是應(yīng)該避免過度設(shè)計济似。相對來說重要性較低矫废。一個事實是,缺乏設(shè)計的代碼比比皆是砰蠢,過度設(shè)計的代碼在實際工作中比較少見蓖扑。
有時正確性被視為外部質(zhì)量,擴(kuò)展性台舱、可讀性和沒有多余部分被視為內(nèi)部質(zhì)量律杠,衡量內(nèi)部質(zhì)量的標(biāo)準(zhǔn)是變動成本,評價外部質(zhì)量可以用客戶需求的滿足度來看竞惋,有些時候也可以用故障率來描述柜去。內(nèi)部、外部質(zhì)量從長遠(yuǎn)看拆宛,是一致的嗓奢。不易擴(kuò)展的代碼,它不可能長期正確浑厚。我們需要時刻牢記“變化”是客戶對軟件最核心的需求蔓罚,沒有之一。
軟件設(shè)計落地遇到的問題
軟件設(shè)計的核心目的是提高系統(tǒng)的可擴(kuò)展性瞻颂。具體的方法很多,高內(nèi)聚/低耦合郑象;XP贡这;SOLID原則;設(shè)計模式厂榛;clean code + refactoring盖矫;TDD;DDD….這個藥方還可以開很長击奶。都非常有道理辈双。但實際落地的過程中,會面臨一些問題柜砾,包括:
1.軟件設(shè)計原則和方法難以有效的大范圍推廣
SOLID\CC\設(shè)計模式\TDD等莫不如是湃望。究其原因:
a)難學(xué)。是對代碼設(shè)計有追求的人其實并不多痰驱;包括喜歡coding的人证芭,也往往對設(shè)計沒有興趣(實現(xiàn)功能和以良好的擴(kuò)展性實現(xiàn),本來就是不同的事情)担映;工作中废士,公司\項目更是未必會給員工大量相關(guān)的培訓(xùn)機(jī)會;何況也未必有合適的老師蝇完;
b)難用官硝。良好設(shè)計帶來的是長遠(yuǎn)的好處矗蕊,而且需要長期的堅持,眼前就要給予相當(dāng)?shù)耐度肟偛皇翘貏e令人愉悅的事氢架。原則的理解傻咖,模式的選擇非常依賴個人的能力,缺乏非常具體標(biāo)準(zhǔn)和具有一定強(qiáng)制力的手段达箍。類似代碼走查没龙,結(jié)對編程這種方法,道理上有用缎玫,但對于大型項目(數(shù)百人)能成功堅持的罕見硬纤。代碼走查,對保證業(yè)務(wù)邏輯可能有用赃磨,但對提升設(shè)計很難說有用筝家。一言以蔽之,沒有標(biāo)準(zhǔn)邻辉。單一職責(zé)溪王,開放封閉都只能是理想。還可以用一些強(qiáng)制手段值骇,比如用自動檢查工具莹菱,度量函數(shù)行數(shù),和圈復(fù)雜度吱瘩,甚至檢查一定程度的重復(fù)代碼道伟。從結(jié)果進(jìn)行約束可以倒逼設(shè)計,但既不能逼出良好的設(shè)計使碾,同時整個系統(tǒng)在邏輯上仍然會缺乏一致性蜜徽;
既難學(xué),且難用票摇,不能形成正向反饋拘鞋,成功推廣自然是緣木求魚。
2. 對人員能力不同要求難以拆分到角色
對于某些系統(tǒng)(比如通信系統(tǒng))矢门,我們希望程序員有下列技能盆色,業(yè)務(wù)能力、軟件設(shè)計能力祟剔、高性能編程能力(對芯片和內(nèi)存系統(tǒng)的親和性)傅事、組織協(xié)調(diào)能力。哪一點做透到都很難峡扩,何況都懂(順便說一句蹭越,別隨便就說自己精通c/c++/Java)。
人類自工業(yè)化以來教届,亞當(dāng)斯密指出的分工帶來效率响鹃,無數(shù)次的被證明有效驾霜,分工合作是正途÷蛑茫可以嘗試去建立學(xué)習(xí)文化粪糙,學(xué)習(xí)型組織,軟件設(shè)計落地寄希望于此就有些一廂情愿了忿项。
如果不能有效的將不能能力需求拆分到角色蓉冈,一定會有某些能力(價值被放棄)。而這些要求要求中轩触,看起來軟件設(shè)計能力是最容易被放棄的寞酿。
但如何有效分解,實際上并不容易脱柱》サ可以考慮建立不同的角色,架構(gòu)師榨为,業(yè)務(wù)分析惨好,軟件設(shè)計,開發(fā)等随闺。但他們之間的工作邊界并不容易厘清日川,前一級的工作內(nèi)容很難有效的傳遞到后一級。須知矩乐,文檔從來都是不靠譜的龄句。
分解對人員能力的要求,帶來的另一個好處是绰精,抵御人員流動,這也是非惩父穑現(xiàn)實的問題笨使。
下一部分講如何以DSL為突破點,并采用相應(yīng)的方法族實現(xiàn)有效良質(zhì)的軟件設(shè)計僚害,并且據(jù)此分解對人員能力要求硫椰,并有效傳遞不同分工間的工作成果。
一個預(yù)警: DSL不是銀彈萨蚕,不是一種能獨立發(fā)揮巨大作用的技術(shù)靶草。它需要豐富友好的其它設(shè)計方法配合,比如包括抽象領(lǐng)域概念建立領(lǐng)域的視圖岳遥,分層奕翔,模塊化(意味著清晰的邊界),以及通過各種方式對系統(tǒng)進(jìn)行有效的拆分和組合浩蓉。它只是眾多工具/方法中的一種派继,但它有希望成為改善軟件設(shè)計的突破點宾袜。