如果你也是一名程序員档址,那么相信從你第一天學習編程起,就會被灌輸很多關于軟件開發(fā)中的法則闻察,它們有些來自于課堂拱礁,有些來自于書本,還有些則來自于工作中前輩的教導蜓陌。我們總是努力地去學習這些法則觅彰,然后再將它們傳授給更多后來人。然而钮热,我們是否只是不假思索地接受它們,而沒有真正嘗試著去理解過這些軟件開發(fā)中的法則呢烛芬?在這篇文章里隧期,我將嘗試通過來自開發(fā)、測試以及流程3個不同方面的問題赘娄,談談我對這些軟件開發(fā)法則的認知仆潮。
面向對象?
今天我們在軟件開發(fā)時最常使用的編程語言遣臼,如Java性置、C++、Python揍堰、Swift等等鹏浅,都無一例外地支持面向對象的編程特性。而那些有關程序員的招聘信息中屏歹,也幾乎都能看到“具備面向對象的程序設計和開發(fā)能力”的要求隐砸。盡管大部分程序員都能熟練地背出面向對象編程的三大特性:繼承、封裝蝙眶、多態(tài)季希,但似乎他們對面向對象的認識也僅僅停留在了這些概念以及某一種編程語言的實現(xiàn)語法上了。我之前曾提到自己在考察程序員時經(jīng)常使用的方法幽纷,我會讓應試者嘗試用面相對象設計的方法來描述面試所在的房間式塌,結果卻發(fā)現(xiàn)大部分面試者無法給出令人滿意的答案,甚至有些人完全沒有思路友浸》宄ⅲ可見程序員們雖然都會在簡歷中寫上自己精通面向對象編程,但實際卻沒并沒能真正理解它尾菇,更別說使用面向對象的思想去解決問題了境析。
面向對象并不是一句假大空的口號囚枪,它其實為我們提供了一種思維方式,幫助我們更好地進行軟件的構建劳淆、組織以及復用链沼。但要想掌握這種思維方式卻并不簡單,這有點像我們都知道正確的價值觀應該是怎樣的沛鸵,但一旦需要應用到自己身上卻很難做到一樣括勺,面向對象的思維方式需要通過不斷的實踐運用才能獲得。然而大部分程序員并沒能這么做曲掰,或者說沒有機會去進行更多的練習疾捍。今天的開發(fā)與以往相比已經(jīng)大大簡化了,那些底層需要復雜抽象的設計都有了可以直接拿來使用的框架栏妖,程序員要做的更多是基于這些框架去寫業(yè)務實現(xiàn)邏輯乱豆。雖然開發(fā)變得更簡單了,但這卻在一定程度上減弱了我們的編程能力吊趾,也出現(xiàn)了很多程序員不會編程的事例宛裕。當我們需要運用面向對象的思維去進行分析和設計以解決那些復雜問題時,往往就會覺得力不從心论泛,無法精準地完成它們揩尸。
我所看到另一個更讓人擔憂的問題是,很多程序員錯誤地認識了面向對象屁奏。例如岩榆,他們會想當然地認為,面向對象就是把任何實體描述為一個DTO(Data Transfer Object)坟瓢,用Getter勇边,Setter方法去存取它們的屬性,然后在其他業(yè)務組件中去處理它們载绿。這的確是一個常見粥诫、也在大部分編程書籍中被作為代碼示例的應用模式,但我想說DTO崭庸,你真的被濫用了怀浆。當你必須把所有實體看作DTO時,本身你的編程思維就受到了限制怕享,你所開發(fā)的程序也將變得機械执赡、缺乏擴展性,越來越難以維護函筋。DTO只是面向對象中描述對象的一種形式沙合,你應該以更高的緯度去判斷一個實體應該如何表現(xiàn)。比如跌帐,數(shù)據(jù)庫中的某一條記錄首懈,它既可以通過那些OR Mapping框架被映射為DTO绊率,同樣的,你也可以創(chuàng)造一個類似Record這樣的鍵值對的類來表示它究履,而后一種往往在批量數(shù)據(jù)分析滤否、報表加工等場景下更加合適。
我們需要具備面向對象的編程思維最仑,但在我們沒有真正擁有它之前藐俺,也千萬不要被那些已有的原則、模式和框架束縛住你的思維泥彤,多看那些優(yōu)秀的程序欲芹,并認真思考自己的每一次的程序設計,及時進行總結和反思吟吝,你將會從中逐漸獲得超越面向對象本身的正確編程思維菱父。
測試非常重要?
測試的重要性不言而喻剑逃,從倡導進行單元測試滞伟,到TDD(測試驅動開發(fā)),我們似乎對程序員進行嚴格的測試并保證代碼質量有了越來越高的要求炕贵。今天,有很多開發(fā)團隊都會要求程序員們采用TDD等方式來測試他們的代碼野崇,甚至還會通過測試覆蓋率等指標來對程序員進行考核称开。這不禁讓我想到,我的一位馬來同事曾經(jīng)為了滿足公司代碼注釋行數(shù)要求乓梨,而把一行注釋硬是拆成每個單詞一行的趣事鳖轰。我們是不是又一次為了滿足某種教條而本末倒置地去做一些不那么必要的測試了呢?
測試不是為了證明那些必然正確的東西:我始終認為程序員們自己是最明白哪些功能需要測試的扶镀。如果這一點是成立的蕴侣,那又何必要求他們去為每一個功能或方法寫測試案例,又或者讓他們在開發(fā)之前就去編寫完整的測試用例呢臭觉?測試一定是被用來證明特定需求是否得到滿足的昆雀,你應該為那些可能存在不確定性的需求或者對外提供的服務來編寫全面的測試案例,而不僅僅是為了滿足測試覆蓋率蝠筑,去給那些明明知道必然正確的實現(xiàn)細節(jié)做測試狞膘。
測試無法提高代碼的質量也不會讓代碼更易于維護:有人說測試是為了提高代碼的可維護性,是為后來人而寫的什乙,但在我看來挽封,代碼才是能夠決定可維護性的唯一條件,如果開發(fā)者的思路清晰臣镣,代碼又寫得優(yōu)雅而具有條理辅愿,那它必然是可維護性好的智亮。反過來,盡管有那些自動化測試案例点待,但代碼卻寫得非忱龋混亂,這樣的程序同樣難于維護亦鳞。完善的測試確實能夠有效保證程序的準確性馍忽,使得我們每次修改可能造成的錯誤風險降低,但我們仍然需要優(yōu)秀的代碼來提供良好的可維護性燕差。
測試的方法很多:關于如何測試遭笋,我們也不應機械地僅僅去應用那些所謂的自動化測試,在一些較小的徒探,或者需求存在不斷變更可能的項目中瓦呼,我們完全可以用人工測試的方法去快速判斷一個功能是否準確,而不是每次需求發(fā)生變化测暗,就去重復地寫一個測試案例以及一套實現(xiàn)央串。當需求穩(wěn)定下來之后,我們還可以完善測試案例碗啄,讓它們可以在未來被重復執(zhí)行质和。總之稚字,根據(jù)項目情況和環(huán)境饲宿,靈活地決定最合適的測試方法。
集成測試越早越好:最后我想說胆描,集成測試必須盡早去做瘫想,我看到很多項目中出現(xiàn)的問題,往往是系統(tǒng)間的接口沒有盡早約定和測試驗證所導致的昌讲。雙方都錯誤地認為對方會在接口中提供這樣的功能或數(shù)據(jù)国夜,但最后卻發(fā)現(xiàn)他們的理解存在偏差,這往往需要極大的代價去修復這些問題短绸。盡早進行集成測試车吹,甚至前期使用一些Mock數(shù)據(jù)來做驗證,能夠有效保證系統(tǒng)開發(fā)的平穩(wěn)進行鸠按,以及團隊間更加順暢的協(xié)作礼搁。
那些層出不窮的方法論?
幾乎每隔2目尖、3年我們就能看到軟件開發(fā)領域誕生一套新的方法論馒吴,比如在軟件架構領域,我們經(jīng)歷了面向模塊、面向組件饮戳、面向服務(SOA)直到今天我們提出微服務架構豪治。而在開發(fā)流程與團隊協(xié)作領域,我們又經(jīng)歷了從瀑布式和工程化的開發(fā)方法到敏捷扯罐、XP负拟、Scrum開發(fā),以及今天我們經(jīng)常掛在嘴邊的DEVOPS歹河。每一種新方法論或思潮的出現(xiàn)掩浙,都會伴隨著新一輪大規(guī)模的系統(tǒng)改造,同時也會對團隊協(xié)作方式產(chǎn)生巨大影響秸歧。當我們對這些新的潮流趨之若鶩之時厨姚,是否也曾想過這些最新流行出現(xiàn)的原因,以及它們是否真的適合你的企業(yè)或團隊呢键菱?
我曾作為甲方參與由一家知名咨詢公司所組建的開發(fā)團隊谬墙,團隊的任務是開發(fā)一套集團內部的電銷核心系統(tǒng)。這個開發(fā)團隊號稱采用了Scrum的管理方式和流程经备。但我卻很快發(fā)現(xiàn)拭抬,那些所謂的Scrum方法往往只是停留于表面的形式而已,例如侵蒙,每日的Standup晨會造虎,團隊成員們只是例行公事般報一下流水賬,而在開發(fā)過程中所采用更小的迭代以及每日集成等方法纷闺,也由于團隊成員技能的參差不齊累奈,而經(jīng)常導致項目版本的延誤,或者因不必要的等待造成的開發(fā)效率低下等問題急但。與之類似,諸如結對編程等在國外流行起來的開發(fā)方式搞乏,我也幾乎從未在國內開發(fā)團隊中看到成功的實施案例波桩。
那么,我們又應該如何看待這些層出不窮的方法論呢请敦?在我看來镐躲,這些所謂方法論都出現(xiàn)在不同的時代大背景之下,又與當時的技術環(huán)境緊密相關侍筛。比如SOA最流行的時候萤皂,恰恰是那些大型企業(yè)為了應對內部日益復雜的業(yè)務需求而提出的,而作為它的基礎設施提供者匣椰,像IBM裆熙、Weblogic、Oracle等一批中間件服務廠商也在那個時期獲得了快速發(fā)展。而今天微服務架構以及DEVOPS的出現(xiàn)入录,則是為了應對如今互聯(lián)網(wǎng)環(huán)境下需求快速變化蛤奥,以及越來越復雜的運維場景而產(chǎn)生的,它們更是與當前云計算僚稿、大數(shù)據(jù)等領域的飛速發(fā)展緊密相關凡桥。不難發(fā)現(xiàn),無論是軟件架構還是開發(fā)協(xié)作蚀同,這些方法論都在引導著我們向更小缅刽、更高效以及更能適應變化的方向發(fā)展。對任何企業(yè)或團隊來說蠢络,永遠沒有什么萬能的方法論衰猛,你需要根據(jù)自己企業(yè)所面臨的問題和目標,來對這些流行的業(yè)界最佳實踐進行深入的切割或補充谢肾,從而得到對自身最行之有效的實踐方法腕侄,而不要像趕時髦般去急著應用用那些所謂最新技術或方法。
程序開發(fā)領域中還有著很多可以拿來探討的問題芦疏,通過對這些問題的思考冕杠,我們發(fā)現(xiàn)在軟件領域并不存在那些非黑即白的所謂真理或法則。程序開發(fā)的美妙之處在于酸茴,它是一種深入的腦力活動分预,充滿著令人興奮的變化和各種抽象思維,我們在一次次選擇和解決問題的過程中獲得進步薪捍。因此笼痹,不要被任何思想、教條酪穿、方法論束縛住你的思維凳干,只有這樣你才能體會到程序開發(fā)中的真正樂趣。