在做系統(tǒng)架構(gòu)時,一個重要的思考方向就是如何讓系統(tǒng)擁有高擴展性烤咧,高擴展性本身目的就是能夠快速響應(yīng)變化帶來的新問題偏陪,并解決這些問題。
擁抱變化指的是什么煮嫌?
我們經(jīng)常聽到這樣一句話:擁抱變化笛谦。
作為開發(fā)人員如何擁抱變化?被動的接受需求昌阿,然后埋頭苦干饥脑?還是高高興興的接受需求,然后埋頭苦干懦冰?這兩種都不是我們期望的擁抱變化的方式灶轰,因為這兩種方式只是心理、心態(tài)上的不同刷钢,在擁抱變化的技能上依舊沒有什么明顯的變化笋颤。
在 《為什么要關(guān)注代碼的可讀性?》這篇文章結(jié)尾中給出了一些線索内地,這些線索不單單能夠提升代碼的可讀性椰弊,同時能夠帶給我們在技術(shù)上擁抱變化的能力--讓代碼易讀、易變動瓤鼻。
這些提升技術(shù)擁抱變化的能力主要分為兩類:
技術(shù)部分:
1. 熟悉工具:[《短時間讓你扔掉鼠標(biāo)的Intellij IDEA的插件》](http://www.reibang.com/p/14e9fed878fd)
2. 開發(fā)語言特性和工具類庫
3. 代碼結(jié)構(gòu)秉版;
4. Simple Design
5. 設(shè)計原則;
6. 設(shè)計模式茬祷;
非技術(shù)部分:
1. 接受反饋清焕;
2. 走出舒適區(qū);
3. 刻意練習(xí)
技術(shù)上擁抱變化并不是僅在某個特定的時間點才去關(guān)注祭犯,不是做架構(gòu)時才考慮高擴展性秸妥,不是出現(xiàn)問題了才去使用技巧來應(yīng)對問題。今年是2019年沃粗,翻翻20多年前的書不難發(fā)現(xiàn)粥惧,早在20多年前人們就應(yīng)該開始整理擁抱變化上的方法,并在20多年的時間內(nèi)不斷喜歡最盅、演進突雪。
本文先來聚焦技術(shù)部分起惕,如何讓我們提升擁抱變化的能力。
技術(shù)上如何擁抱變化
為了讓本文內(nèi)容不至于離大家太遠咏删,就從手邊能做的和技術(shù)相關(guān)的內(nèi)容來說明惹想,如何在技術(shù)上提升擁抱變化的能力。
1. 熟悉工具
你每天用的工具都有哪些督函?Git嘀粱、Intellij Idea、Docker辰狡、Terminal等等锋叨。
熟練使用這些工具在基本功能至上,學(xué)習(xí)和探索如何能夠讓這些工具更為高效的為你工作宛篇。
可以按照下面的清單來審查需要在哪個環(huán)節(jié)提升效率:
1. 基本功能和特性悲柱。例如:git stash、Idea中Refactoring中的功能等等
2. 這些功能的快捷鍵或者alias是什么
3. 工具間的切換如何快速完成些己。
按照上面的清單,不斷提升工具的熟悉程度嘿般,能夠為我們節(jié)省下很多碎片時間段标,將節(jié)省下的時間用在其他地方時爭取時間的好辦法。
2. 開發(fā)語言特性和工具類庫
和工具一樣炉奴,我們使用工具就是為了能夠更加高效的處理日常重復(fù)性工作逼庞。熟悉了解開發(fā)語言特性能夠讓我們事半功倍。將時間留給那些真正需要重復(fù)造的輪子上瞻赶。
下面是幾個簡單的例子:
1. 如何減少代碼中的非空判斷赛糟?
2. 如何將兩個數(shù)組合并?
3. 如何將Domain轉(zhuǎn)為DTO砸逊?
熟悉這些工具類璧南,能夠讓我們有能力快速應(yīng)對一些修改、變化师逸。
3. 代碼結(jié)構(gòu)
沒有一勞永逸的代碼結(jié)構(gòu)司倚。
我們的架構(gòu)在演進,我們的代碼在變的復(fù)雜篓像,并不是簡單定一些條條框框的開發(fā)規(guī)范就能夠?qū)栴}解決的动知。
代碼結(jié)構(gòu)并不是規(guī)范,而是應(yīng)該留意團隊中實際遇到的問題员辩,通過調(diào)整目錄結(jié)構(gòu)來讓代碼相對于之前更清晰盒粮、更易維護。
下面是一些思路:
1. 根目錄下的內(nèi)容存在重復(fù)奠滑、多而分散丹皱,適當(dāng)?shù)倪M行內(nèi)聚妒穴;
2. 已經(jīng)無法通過一個類型的前綴快速定位到一個類,即使通過IDE也需要更對的信息才能夠準(zhǔn)確定位到一個類种呐。
3. 讓整體結(jié)構(gòu)變得混亂的某些包 或者 代碼
4. 職責(zé)越來越大的類和包宰翅,已經(jīng)無法清晰表達業(yè)務(wù),拆分其職責(zé)爽室。
4. Simple Design(簡單設(shè)計原則)
Simple Design正式眾多原則中的一個汁讼,不過對很多問題都適用。
- 實現(xiàn)功能
- 揭示意圖
- 消除重復(fù)
- 最少元素
為什么要用Simple Design阔墩?
通過代碼來實現(xiàn)業(yè)務(wù)需求嘿架,這是我們的目的。如果想要讓實現(xiàn)需求的代碼容易維護啸箫,就是我們在實現(xiàn)的時候就保持其易讀耸彪,易修改,而簡單的事物是容易修改和處理的忘苛。所以讓代碼保持簡單是面對變化蝉娜,能夠擁抱變化一個很好的選擇。
不管是使用簡單設(shè)計原則扎唾、還是熟悉工具召川,其目都應(yīng)該是聚焦價值的,即我們所做的都為為了實現(xiàn)某個價值胸遇。所以Simple Design中四個對代碼設(shè)計活動也就有了一個先后的順序荧呐。首先實現(xiàn)業(yè)務(wù)功能,但并不能僅止于實現(xiàn)業(yè)務(wù)纸镊。為了后續(xù)能夠快速修改倍阐,我們每次實現(xiàn)了部分業(yè)務(wù)代碼后,就應(yīng)該考慮逗威,實現(xiàn)業(yè)務(wù)的代碼中的包峰搪、類、方法凯旭、參數(shù)罢艾、變量是否揭示了業(yè)務(wù)意圖。如果沒有我們就需要修改這些內(nèi)容的位置和名稱尽纽,從而能夠得到一段意圖明顯的代碼咐蚯。
意圖明顯但是充滿重復(fù)的代碼,同樣是不易修改和維護的∨撸現(xiàn)實中發(fā)現(xiàn)很多開發(fā)人員會期望提前將公用代碼做好封裝春锋,例如我們代碼中的工具類,但是在業(yè)務(wù)代碼時卻又將重復(fù)忽略不見差凹。所以消除重復(fù)不是開發(fā)者不做期奔,而是并沒有形成意識侧馅,哪些環(huán)節(jié)都需要去消除重復(fù)。
最少元素呐萌,使的代碼更加簡潔馁痴。例如一個方法的如入?yún)?yīng)該盡可能少,超過3個入?yún)⒕蛻?yīng)該將參數(shù)封裝在一個類中肺孤。話是這樣說罗晕,但是最少元素也是最不好做到的。因為不單單需要我們對開發(fā)語言熟悉赠堵,對業(yè)務(wù)熟悉小渊,還要求對設(shè)計原則,設(shè)計模式有一定的掌握茫叭,才能真正做的最少元素酬屉。
最后,在反問一句揍愁,做這些有價值嗎呐萨?有價值,畢竟修改代碼時莽囤,讀代碼和寫代碼的時間比例時10:1谬擦。保持多簡單代碼,能夠讓我們事半功倍烁登。不過其價值的大小,我認為可以按照上面的1蔚舀,2饵沧,3,4來進行排序的赌躺,實現(xiàn)功能的價值最大狼牺,揭示意圖的價值其次,消除重復(fù)再次礼患,最后是最少元素是钥。
那么什么時候使用Simple Desin呢?
添加新的代碼缅叠、修改舊的代碼時都應(yīng)該遵循悄泥。先實現(xiàn)功能、在用1分鐘審視一遍是否剛才加入的代碼揭示了意圖肤粱,是否存在重復(fù)弹囚,是否應(yīng)該用最少元素。
《從Simple Design入手讓代碼易維護》一文中講解了對Simple Design不同熟悉度的開發(fā)人員如何進一步提升系統(tǒng)的易維護性领曼。
5. 設(shè)計原則
為什么我們在談讓開發(fā)擁有擁抱變化的能力的時候要談到設(shè)計原則鸥鹉?
因為通過設(shè)計原則蛮穿,我們能夠發(fā)現(xiàn)我們代碼中的問題。我們實現(xiàn)的業(yè)務(wù)的代碼之所以不易修改毁渗,很大原因是我們并沒有遵循這些原則践磅,久而久之代碼就越來越不易修改。如果我們維護的一份結(jié)構(gòu)灸异、意圖清晰的代碼府适,設(shè)計原則,有助于幫助開發(fā)人員維持好這份清晰绎狭。
設(shè)計原則指的是哪個設(shè)計原則细溅?
- 單一職責(zé)原則
- 開放封閉原則
- 里氏替換原則
- 依賴倒置原則
- 接口隔離原則
但讓止于上面5種原則,還有很多儡嘶,比如:好萊塢原則(HP)無循環(huán)依賴原則(ADP)等等喇聊,從以上5個原則開始或許是維護好代碼,讓代碼易修改的入手點蹦狂。
上面 5個設(shè)計原則都分別指什么誓篱?
【單一職責(zé)原則】
對一個類或者一個方法而言,應(yīng)該只有一個引起它變化的原因凯楔。
【開放封閉原則】
軟件實體等(模塊窜骄、類、方法等)應(yīng)該是可以活站的摆屯,但是不可以修改邻遏。當(dāng)軟件實體發(fā)生變化時,盡量通過擴展軟件實體的行為虐骑,而不是通過修改已有代碼實現(xiàn)變化准验。
【里氏替換原則】
在繼承時,應(yīng)該遵循里氏替換原則廷没。任何基類出現(xiàn)的地方糊饱,子類一定能夠出現(xiàn)。子類可以活站基類的功能颠黎,但是不能改變基類的功能另锋。(子類可以實現(xiàn)基類的抽象方法,但是不能覆蓋基類的抽象方法狭归;子類可以增加自己特有的方法夭坪;當(dāng)子類的方法重載基類的方法時,方法的形參要比基類的輸入更加寬松过椎;當(dāng)子類的方法實現(xiàn)基類的抽象方法時台舱,方法的返回值要比基類的更加嚴(yán)格。)
【依賴倒置原則】
高層模塊不應(yīng)該依賴底層模塊,二者應(yīng)該依賴與抽象竞惋。抽象不應(yīng)該依賴于細節(jié)柜去,細節(jié)應(yīng)該依賴于抽象。
【接口隔離原則】
不再在一個接口中放置很多的方法拆宛,這樣會讓接口變的臃腫嗓奢;接口應(yīng)該盡量細化,一個接口對應(yīng)一個功能的模塊浑厚,同時接口中的方法應(yīng)該盡量少股耽,使得接口更加靈活。
6钳幅,設(shè)計模式
開發(fā)者可以通過設(shè)計原則來發(fā)現(xiàn)問題或者確定修改思路物蝙,通過設(shè)計模式來解決問題。
設(shè)計模式并不是唯一解決問題的途徑敢艰。我們必須先來聚焦我們?yōu)槭裁匆迷O(shè)計模式诬乞。還是為了讓代碼擁有擁抱變化、易修改的能能力钠导。遵循設(shè)計模式是讓程序擁有這種能力的一種實現(xiàn)方法震嫉。
對于那23種設(shè)計模式,會在后續(xù)整理出來牡属。
結(jié)尾
讀到這里估計很多人開始想票堵,我要擅用工具,又要使用Simple Design逮栅、設(shè)計原則悴势,最后還要用上設(shè)計模式,感覺繞了很大一個圈子措伐?是的特纤,不過是圍繞價值來的。如果不熟废士,那么循序漸進或許是一個好的選擇叫潦。如果對上面的很熟蝇完,當(dāng)遇到一個問題時官硝,上面的過程只是瞬間完成的。
不管對上面的內(nèi)容熟悉與不熟悉短蜕,關(guān)鍵點不要忘記氢架,都是為了讓開發(fā)者真正具有擁抱變化的技術(shù)能力。
最可怕的人是那些注重細節(jié)的人并行動的人朋魔。