把代碼寫的太靈活不好嗎?為什麼會被上司批評?
個人有四年的代碼開發經驗。習慣加註釋,以及把代碼寫的靈活一點,比如說增刪改查的系統操作日誌,我習慣配置文件加一個是否寫操作日誌的配置然後根據配置來判斷是否寫系統操作日誌。這樣有問題嗎?為什麼別人會說沒必要?不明白
每增加一個間接層都可以解決更通用的問題。
但軟體設計中各種指標都是互相影響的,更高的彈性可能增加複雜性、開發/維護成本、代碼體積、性能開銷等。
所以,設計的難處在於平衡各種指標,而你和上司所想的平衡點可能是不同的。
避免 overengineering。
圖片來自 xkcd The General Problem
一個好的系統,靈活性應當體現在架構設計上,具體到代碼片段,反而是簡單直白的好。
單個樂高積木,遠不如一小塊橡皮泥靈活。但上千個樂高積木,卻可以拼出各式各樣的模型,而上千塊橡皮泥堆在一起,卻不一定能支撐自身的重量。
為什麼?
因為樂高類積木的靈活性體現在架構上,規定了標準的尺寸和介面,只要符合規定,不同品牌的積木亦可以拼插進來。而具體到單塊積木,則形狀簡單,介面明確,穩固可靠。而小塊的橡皮泥,雖可以捏成任意形狀,但當系統變大時,則無法維護。
好的代碼模塊,也應像單塊積木那樣,簡單,健壯,可靠,介面明確,可以把一件事做好,可以在任何環境下做,單線程,多線程,IO延遲,垃圾輸入... 不崩不慫,才是好的,也是重用的基礎。
具體到題主的情況,不妨考慮一下,新加進去的配置別人是否遵守,如果不是所有人都採用,其他人是所有的操作都進日誌,只有題主的模塊根據某個flag決定寫或不寫,系統集成後,debug 時會相當的困惑,將來也不易維護。
如果是這種情況,我也是建議不加的。
不不不,代碼寫的很靈活沒什麼問題,但是不要讓用的人知道。
現在老闆要你去做個電飯煲,你做一個智能淘米煮飯炒菜一體機出來是沒有問題的,問題是你那玩意兒得和電飯煲一樣按一下按鈕就能煮出飯來並且可靠性不比電飯煲差。
如果你確信你那玩意兒確實如上面所說的那樣簡單,那就是你上司管太多了。
KISS-Keep IT Simple, Stupid
代碼和程序員必然有一個 Simple and Stupid 定律。You aren"t gonna need it!
也算是IT界的老話了,沒有確實的需求,不要加功能。有時候需求真的只是一個汽車輪子,不需要你造出可大可小,上可配飛機,下可配嬰兒車的全能輪。嗯,就比如說日誌系統吧,你如果要讓它可配置,那顯然不是一個選項搞定的,一般來說標準的日誌系統,都是按照組件、級別可以輸出到不同的文件或者控制台或者遠程系統或者不輸出等等,Python的logging、Java的log4j、還有syslog都有這樣的功能。如果你們最終是通過這些成熟組件輸出出來的,那這些組件全部都自帶配置功能,功能遠遠比你這一個開關要豐富,那正常情況下顯然並不需要你再去加一個選項了。
再說你把選項做成配置文件的問題,這個配置文件是只有你這一個模塊使用嗎?以後上線了,誰負責維護這個配置?配置文件的位置怎麼跟其他組件的配置文件協調?配置什麼時候載入,是否支持熱重載,如果配置文件損壞了或者丟失了會不會導致整個系統起不起來?我們再說測試的問題,你加了這麼一堆代碼,將來都是可能要用到的,那就需要設計測試例,需要進行額外的測試,這些都是需要統籌考慮的問題。
我們不說是否過度設計的問題,其他人已經說得挺好的了;你這裡首先就涉及一個工作方法的問題。聽你描述,我認為老大並沒有把整個系統的設計全部交給你負責,就算整個系統讓你自己設計,也應該有個評審的過程,那如果是已經做完了的設計,你卻沒有按照設計開發,而是加了額外的、需要改變其他環節工作方式的內容,你就應當提前跟相關人員協商,這個你認為應當增加的功能應當怎麼設計,怎樣最大程度上和整體設計協調,雖然代碼是你寫,但不一定是你調用,不一定是你測試,不一定是你運維,這些都涉及到別人的工作,你不打一聲招呼去影響別人的計劃自然是非常有問題的,更不要說可能因為你額外做的這些工作而延遲了完成時間,增加了額外的bug,這就顯得不太專業、不太負責任了,所以你老大生氣合情合理。本質上來說都不是靈活不靈活的問題,而是你根本沒有盡到一個團隊協作人員應盡的職責。
「代碼靈活」和「吃飽了撐的」有時候界限是比較模糊的。
比如寫一個組件吧,需要設置一些參數才能使用。差的方式是把參數在代碼里寫死,好一點的方式是寫一個config函數介面把參數傳進去,再好一點的方式是有config函數介面,但是組件自帶最常用的默認值,不設置也能跑。
自以為代碼靈活但其實是吃飽了撐的方式是:寫一個配置文件,再寫一個config函數介面用來傳配置文件的路徑。於是這個組件的代碼除了核心代碼,還牽涉到了文件系統,XML(或者JSON,或者其他什麼格式)解析,誰要用這個組件還得學習配置文件的格式是什麼,該放哪個目錄。。。你以為這個了不起的尖端組件需要如此靈活,一定是用來下圍棋的,其實它就是個寫日誌的logger而已。先寫一個你認為最兼顧靈活和易用的介面,再寫一個最靈活的介面包裝和一個最易用的介面包裝.
日誌本身是有級別的,一般的做法是配置這個級別。比如說我們日常打日誌都是debug級別。
就題主的這個問題來說,題主的做法完全是多餘的。因為級別的控制方式顯然更合理,更自然。
靈活的設計的意義其實是在對業務系統的抽象之上。這個其實挺難做到的。需要對業務以及技術的理解和認識。記得之前在大學的時候,項目組的phd為了「模塊化」開發的需要,把一個自動化測試工具分成了4個獨立步驟:路徑選取、約束求解,用例構成、編譯執行
看上去很美好,然而第二個模塊的負責人經常抱怨從第一個模塊拿過來的path很多都是infeasible或者難以滿足,因為路徑太奇葩了,不知道該怎麼提取路徑約束;好不容易過了第二個模塊,第三個模塊的人就抱怨了,說第二個模塊生成的約束怎麼這麼多,還有一堆相互矛盾的,根本生成不了測試用例啊;搞了半天,把矛盾的約束剔除了幾個,生成了一個testcase,到了第四個模塊的負責人就怒了,說你們生成的這個testcase啊,怎麼包含這麼多非法變數名,程序根本就沒聲明過的變數在testacase table裡面一大堆,還有,為什麼有些程序的的輸入參數不指定數值呢?根本就通不過編譯好嗎!
後來boss來看了我們的設計架構,說你們這個設計想法,很好很天真,首先這個路徑選擇,是依賴於約束求解的,否則你沒法判斷路徑是不是infeasible的;其次,你這個路徑內部採用的是全路徑選取,但是你要考慮後面的約束求解的難度啊,不難隨便亂選路,還有這個用例構成必須為前面的約束提取生成一個template,指定一些輸入的必填項,要不然你約束提取不完整導致後面編譯通不過怎麼辦。看上去是四個獨立的過程,其實根本就不能獨立開來實現。
軟體工程里經常強調封裝和模塊化,但是在你實現一個原型之前,你是不太可能知道,哪些部分需要封裝,如何模塊化介面的,如果還沒寫出功能來,就直接模塊化,搞個general interfaces,那估計多半後面是用不上的,甚至非常浪費工時。所以在很多工程實踐中,我們往往是讓程序員先把各個模塊基本功能寫的差不多的時候,再通過重構來提取通用化介面,當然了,比較學術化的程序可能到處都是general interfaces,不過嘛,像公司里這種deadline-driven-development,哪有人有功夫管那麼多通用化的東西,估計連重構的功夫都沒有呢,這也是為啥現在代碼看著就像一坨shit,雖然它們都能work就是了性價比。
任何超出當前需求的代碼都是浪費。儘早高質量的完成當前需求,讓它上線運行,分析客戶操作習慣和反饋。然後你可能會發現你預留的一些靈活性未來一百年都用不到,反倒會在重構時成為障礙。
可能確實就是沒有必要。
未必有更多意思,比如未必批評你做的不對,未必覺得你不應該做,只是覺得沒有必要做。你如果做了,也沒什麼關係,多鍛煉鍛煉未嘗不可。
不要過度設計,不要腦補出不存在的需求。
萬一來了新需求怎麼辦?改唄。 @鄭子穎 說得很不錯,很中肯。
恰到好處的用力,把代碼寫得平易近人,也是高手的風範。
按照《人月神話》的說法,可變性和複雜度都是軟體的本質特性。寫的靈活的目的是適應變化,但是會增加複雜度。至於好不好,就看你寫的靈活的點會不會變化了。預測變化其實是核心能力,自顧自的「寫的靈活」是不對的。
《深入理解C#》(第三版)中第128頁的建議:
……但我強烈建議你主動思考,以在簡潔性和可讀性之間取得平衡,並和其他團隊成員商議,盡量在編碼風格上取得一致。但是(儘管),一致的編碼風格並非總是能夠產生最易讀的代碼……
很多時候,靈活性和可讀性之間是有矛盾的。
靈活是相對的,你覺得靈活,可能再過幾個月你就會發現這樣還不夠靈活。
但是靈活意味著維護成本,就像我要一杯咖啡,你要問我什麼咖啡,加糖嗎這些問題,是沒問題的,如果你非要靈活性,再問一些其他的,比如要多少,濃度多少,要多熱的,什麼杯子,巴拉巴拉一大堆,你覺得即使你完成了客戶最想要喝的咖啡,但是客戶絕對不會想再來你這了。。
從用戶的角度上看,我只要一杯咖啡,至於具體要什麼樣的,請幫我配置好模板,起一個明白的名字,我只要選一次就好,至於你能做到多細,我不管,我也管不了。
從技術人員的角度上看,參數越多,越靈活,這是沒錯,但如果人家只是要一杯可樂,你做了一個自動飲料售賣機,你不是給自己找不自在嗎?
我的能力就是我的能力,我不需要把我所有的能力都在一個項目里展現出來,那會給人一種暴發戶的感覺。
這個問題在我的首頁出現了好幾天,手癢過來念叨幾句。
1,討論問題前學會放低姿態
這是個簡單的道理,卻是個大家都忽視的道理。一開始就認定自己是對的別人是錯的,根本無助於解決問題也無法從得到進步。
題目的描述不是疑問句而是陳述+吐槽。本以為能從回答中收穫安慰,然而現實卻。。焦作人了。
其實這個問題是一個很好的契機,可以看出自身的不足。
「習慣加註釋,以及把代碼寫的靈活一點」。這句話看似政治正確,實際上很多情況反而會造成問題。
假如能在事情發生後,冷靜思考下,相信能收穫更多。
2,代碼太靈活是好是壞?
從題目描述看,題目中所謂的靈活,其實是一種懶惰。
「我平時習慣怎樣怎樣」 所以 「寫日誌我要用配置文件」。
可以推斷出,題主並沒有經過思考,沒有考慮該場景是否需要「這麼靈活」,就直接套用了自己慣有的開發模式。
回到話題本身,「靈活」可能有好有壞,但「太靈活」,只會增加維護成本以及出現問題的風險。
假如這裡的「寫日誌」邏輯是必須要存在的,現在將它變成「可配置」,一方面多出來的「判斷當前是否需要寫日誌」這些代碼可能有出問題的風險,另一方面配置文件的出錯也會導致伺服器連日誌都沒有,最後,因為配置文件的存在,人為操作的風險也要算進去。
顯然,這裡「太靈活」是多餘的甚至是錯的。(上述觀點建立在「寫日誌」邏輯時必須要存在的條件下,假如「寫日誌」邏輯不是不要的,那就需要重新考慮了 —— 總之就是要根據實際場景判斷,不要無腦套用一個開放模式、習慣)我還曾經因為聽UX和PM的話把全部東西都做了,被批評(逃
你可能得重新審視一下你們開發的軟體的各項指標,包括並不限於,應用範圍,開發計劃,開發進度,維護計劃,長期目標,現有複雜度,團隊水平,等等。要是你不太明白這些是什麼鬼並且不明白這些怎麼跟「靈活性」做tradeoff的話,就聽你老闆的吧。
這世上有種東西叫編碼規範!寫不寫日誌,怎麼寫日誌,寫什麼日誌,什麼時候寫日誌都是可以規範的。一般來說,如果是項目開發就以需求方的規範為準,需求方沒有要求或是產品模式開發就以項目組要求為準,項目組沒有以自己頂頭上司的要求為準,都沒有就自己定一個並堅持執行,同時在必要時更新規範。。。如果客戶或項目組或上司的規範不合理,可以提出來討論,如果你的意見有道理,也許對方會接受並更新自己的規範。不過不管結果如何,該遵守規範還是要遵守,不能因為你覺得沒道理就不遵守。當然,如果對方事先沒有要求,你寫了他又有意見,那就和他好好溝通,也許人家能講出一番道理,如果對方就是無理取鬧瞎BB,那就看你能不能幹過他,幹得過就別理他,他不能把你怎麼樣,干不過就認慫,不吃眼前虧。但是,不管是那種情況,都不應該只是以你的"習慣"為出發點,記住我們是以理服人。。。
推薦閱讀:
※當你學會了什麼之後感覺自己的編程算是入門了?
※程序員必須掌握哪些演算法?
※為什麼點贊手速過快會出現計贊 2 次?
※零基礎自學 Android 並去找工作可行性大么?
※「傳輸自動生成代碼並執行、生成所需文件」能否成為未來的下載方式?