「妥協」,這個詞可能在大多數的情況下,我們都會覺得帶有負面的意思。

因為,「妥協」通常意謂著不是「理想的」,也就是說,你明明知道有理想的方式,卻做了一個不夠理想的選擇。相反的,「堅持」、「不妥協」,感覺起來就正面多了。

而對軟體工程師來說,「堅持」、「不妥協」聽起來就相當熱血。

因為設計過程中想偷懶,在一時錯亂下,所以我們妥協了

不過,我們回過頭來想,什麼情況會需要妥協。程式設計者會想妥協,最常見、也最說不過去的理由就是偷懶。從「重構」中的諸多「壞味道」中,你就可以觀察出,程式碼會逐漸腐敗而產生「壞味道」,而腐敗的主因之一,就是程式設計者的「偷懶」。

例如,我在某處 A 寫了一段程式碼,剛好在另一處 B中也會用到類似的,但我就「偷懶」了一下,直接把 A處的該段程式碼複製到 B 處,甚至再予以小小的修改,以滿足 B處之所需。這麼一來,程式碼就多敗壞了一些。

程式設計者或許不知道這麼做是不好的,或許也知道。例如,程式設計者可能明白這樣「複製再貼上」程式碼的舉動,有損程式碼的品質,但是,想偷懶的念頭大過於維護程式碼品質的堅持,所以一時意亂情迷,就直接複製貼上了。

我還可以舉出更多這樣子的例子,在部份程式設計者的開發生活中,就是充滿著「將就」的決策,反正呈現出來的效果差不多,堅持原則的正念輕易的被偷懶的邪念給擊潰,所以程式碼腐敗的速度就很快了。

如果程式設計者在面臨此類的抉擇時,例如,遭受到「複製貼上」的黑暗面心靈力量誘惑時,可以斷然拒絕誘惑,而是選擇將 A 處和 B 處對於這段程式碼的需求,整理出一個共通的部份,將其提煉成一個函式或是類別,並且分別在 A 處及 B 處運用該函式或類別。這麼一來,就可以阻止程式碼往腐敗的方向發展。

因為沒有足夠的時間和資源,所以我們不得不妥協了

有些時候,不是因為程式設計者想要偷懶,而是因為其他的現實條件所產生的限制,例如大家最常碰到的「時程壓力」。

一個任務,有不可錯過的時間,但是時間的充裕程度只允許完成一個不夠理想的快速方案。程式設計者心裡明白如果有充裕的時間,他可以完成一個更理想的方案,但是,現實條件就是時間不夠充裕。程式設計者可以選擇錯過時間,或者是選擇不理想、進度卻趕得上的方案。

但在現實的人間,總是要食煙火,並不是所有的條件都能無止盡地予以理想化。尤其最常碰到的限制條件就是資源(人力)和時間。對商業的活動而言,很多時候,時效是很關鍵的因素。如果完全回歸到理論上的最理想化,那麼,有些時候,就勢必會錯過時效,而軟體本身的存在,也有可能因此而失去意義。

面對現實,明知必須妥協,但仍有辦法找到方法因應

所以說,這些現實的限制條件是必須要予以重視的。但是,這麼一來,對於理想的堅持,難免就在此處打了折扣,這就是本文的主題「妥協」。

對於心態隨便的程式設計者來說,「妥協」是家常便飯,因為他們可能不時的在妥協。

但是,對於理想性強的程式設計者來說,「妥協」反倒是一件痛苦的事情,因為他們明白知道可以做的更好,卻因為現實的關係,被迫選擇一個將就的方案。因此,「妥協」反而成了一門需要學習的課程。

以前談過「技術債(Technical Debt)」的議題,所謂「技術債」的觀念,就是把這些在程式設計過程中,因為「妥協」而犧牲的程式碼品質,視為是一種「負債」,也就是說,先向未來預支一些時間,來縮短完成目前工作的時程。

因為向未來預支了,所以,就像是積欠債務一樣,而債務最終仍然是需要償還的,所以,你勢必得在未來多投入時間,才能將程式碼的品質修復到應有的水平。

而且,就跟向銀行貸款一樣,不僅得償還本金,還有隨著時間不斷必須支付的利息。例如,在程式碼修復之前,因為品質不夠好而遭受到的傷害,以及之後修復需要花費的代價,往往也會高於在第一時間點就把程式碼寫好。

有些人對於技術債的看法和評論,太集中在不要欠下技術債,這個也不能說是不正確。然而,我認為,對於程式設計者來說,更全面的認識應該是:(1)了解那些舉動會欠下技術債(2)明白不同的技術債所需付出的代價高低各是多少(3)清楚需要欠下技術債的時間(4)決定償還技術債的時間點。

決定欠下技術債無疑是一種妥協,如果我們試著將程式設計者妥協的情況分級,那麼可能會有以下幾種。

第一種,是不知不覺欠下技術債。因為他對那些舉動會欠下技術債,以及各種技術債所造成的負面影響一無所知,同時,他還不明白更理想的設計方法,所以他的產出中,不時都有這些不理想的設計結果。

第二種是知道自己的某些舉動會欠下技術債,但對會產生的負面效應缺乏深刻的體認或是不在乎。

第三種則是總是不欠下技術債,即使錯過所有的時程,也毫不在乎。

而第四種則是知道什麼時候該欠下技術債、也清楚自己日後需要額外歸還多少利息,也能判斷何時應該要償還所欠下的債務了。

前兩種其實沒太多可談的,本文讀者的掙扎,可能多半來自於後兩種。當然,我認同總是不欠下任何債術債的程式設計者,也佩服他們能夠堅持理想的作法,這終究是做為工程師的驕傲。不過,我也相信,許多軟體的開發終究得面對商業上的現實。

不能趕上時間,有時候,所導致的傷害,會比欠下技術債來的大上許多。工程師若是只關心自己能否完美得實踐原則,而不理會工作是否能如期完成,以達成商業目標,這樣終究還是會製造出缺憾。

因此,我列了第四種類型。這類型的人知道如何運用財務槓桿來做投資,也就是先借一筆錢,然後拿它來投資,得到遠超過利息的效益,之後再從獲利中撥出一部份來償還,這麼一來就是成功的投資。但我覺得許多人對於技術債討論的焦點,往往放在不要欠下技術債,以及技術債會造成的潛在傷害,而不是討論該怎麼運用技術債來投資,以便取得更大的效益。

如何看待技術債?Martin Fowler 大師用兩個維度將欠下技術債的原因,組合成四個象限,第一個維度是蠻幹(reckless)和謹慎(prudent),而另一個維度則是刻意的(deliberate),以及無心的(inadvertent)。

其中,妥善運用技術債的人,會落在謹慎及刻意的象限裡。這意謂著,技術債是刻意為之,而且是謹慎評估處理的。

「妥協」並不全然是隨意或放任態度下的產物,也有可能是謹慎、刻意做出來的決定。也不是所有的妥協都是邪惡的,就像財務槓桿一樣,可能產生更好的投資效應。因此,要做出好的妥協,也是一門學問。

專欄作者

熱門新聞

Advertisement