軟件開發中的陷阱
英文原文:It’s a trap! Systems traps in software development
為了優化某個情況卻發現事情變得更糟了,你曾遇到過嗎?你曾遵循傳統的「最佳實踐」卻發現它未能盡如人意?貌似你嘗試得越多,事情反而變得越糟糕,是這樣吧?
Dana Meadows 寫了一本開創性的、關于系統思維【注1】的作品,《Systems Thinking — A Primer》,她認為大量的系統結構傾向于導致「有問題的行為」。這種典型的「陷阱」,由于未能認識到它們而導致不可預期的問題。這種陷阱在生活的方方面面都極為普遍,軟件開發行業也不乏其例。
本文描述了 Dana Meadows 提出的 8 種陷阱,根據我自己在軟件開發的經歷給出了相應例子。
下面的幾種陷阱,你中招了多少?又該如何撫慰傷口?
策略抵制
策略抵制(policy resistance)或許稱作「固定某個錯誤」更為合適。在同一系統的不同部分的需求之間沒有經過協調時,這種原型就會出現。
舉個非法毒品供應的例子。用戶需要足量的供應,而法律強制少量供應,交易商想讓供應多到足以滿足需求、而少量供應足以維持了高價格。在這個系統中,任何干預將導致其它部分付出雙倍努力才能更好地滿足他們自己的需求。然而改變不了多少。
這是一個例子,平衡反饋回路(feedback loops)會對彼此起著反作用,阻止了有意義的改變。
現在讓我們回到工作場所(如果你是毒品交易商,我下面的話就不用說了),考慮一下技術債務和與之相關的各方目標。開發人員愿意保持較低的技術債 務,如果你是開發人員,理由是再明顯不過了。管理人員也愿意減少技術債務,但是經常迫于壓力而不得不快速地為利益相關人交付東西。這或許需要一種妥協,技 術債務的減少和滿足利益相關人的緊急需求。利益相關人很少關心技術債務(假定質量是已知的),更愿意看到他們的需求被滿足,越快越好。
減少技術債務的期望遇到了增加吞吐量的要求;增加吞吐量的期望遇到了減少技術債務。因此,很少能改變什么。這種陷阱導致了開發人員和利益相關人之間的習得性失助【注2】,在你搞清楚這種處境之前,你發現自己所處的組織,到處彌漫著一種心態,那就是「為什么要煩惱?」。
如果利益各方意識到反饋回路和引發的技術債務之間的延遲,那么這個具體的例子就容易修復了。解決技術債務事實上會導致更高的吞吐量,但是這種收益只有在技術債務被足夠減少時才會顯現。如果你的組織始終以緊急重要的模式運行,這種延遲就不會符合心意。
簡單地說,策略抵制是一個系統內多方之間需求沖突的結果。或許我能建議的終極解決方案,可以簡單地歸結為滿足各方需求。
公地悲劇
公地悲劇【注3】是一種系統的原型,描述了公共資源使用的增加,最終導致其耗盡和最終破壞。重要的是,資源的個體消費者即使知道這樣做會導致減少,仍然會增加他們的消費。
通常被描述為公地悲劇的場景是過度捕魚【注4】。每個漁夫都想抓住更多的魚,即使這樣做將最終導致魚類數量減少和漁夫生計的破壞。公地悲劇的特點是,個人的短期利益對于其他人利益或公共資源的長期需求沒有給予足夠重視。
一個經典的子優化(sub-optimisation)。
在軟件行業,集體代碼所有權可以被視作「公地」,因為不注重長期需求而容易遭到消耗,比如魚的存量、牧場。如果開發人員傾向于交付「價值」,而 以可維護性和可理解性為代價,那么這個問題就特別普遍了。如果是這種情況,每次代碼修改將大大減少其總體質量,最終導致軟件的不可維護。
軟件開發中的其它公地悲劇有:
- 過多進行中的工作,將導致團隊總體產出的質量和吞吐量。
- 多個團隊「項目」的、團隊子優化(現在要當心這些項目了……)。如果動機在團隊層面最為強烈,那么每個團隊只關注他們自己的需求、而非整體需求,請不要對此感到驚奇。
- 對于個人的子優化,開發人員是根據他們自己的績效衡量、而非團隊/產品/組織。 </ul>
- 產品質量不高?雇傭更多的手動 QA 人員,以「專注于質量」,而不是研究自動化測試和持續的交付技巧。更多的手動測試意味著較少地依賴自動化測試,隨著代碼庫的增長,將需要更多的 QA 人員。
- 糟糕的流動效率?雇傭更多開發人員,而不是致力于如何提高流動效率。更多的開發人員意味著更多的溝通和管理,導致降低流動效率,這就需要更多的開發人員。
- 團隊沒有滿足最后期限?堅持加班或「更大的承擔」,而非界定范圍或更聰明地研究參與人員的工作方式。更大的承擔(或我喜歡的吶喊:「更多激情」)導致短期利益,隨之而來的是,長期疲乏、質量侵蝕、效率降低、以及不可避免的對更大承擔的進一步召喚。 </ul>
- 延展性目標(stretch goal)或不切實際的最后期限。某些管理人員信奉,設定不切實際的最后期限,將鼓勵專注和交付。不幸的是,當最后期限變成主要目標時,滿足用戶需求將被劃入次要關心的問題。當最后期限被滿足、而用戶還想要時,請這些管理人員不要感到驚奇。
- 尋求「更加敏捷」。據我看,在幫助團隊更有效率、以及幫助培養一個更加協作、仁愛和專注價值的組織方面,敏捷思維非常有價值。然而,「執行敏捷」可以輕松變成目標,而非完成目標的途徑。把「敏捷」和目標搞混,對于敏捷而言,沒有什么比這更有破壞性的了。 </ul>
- 注1:系統思維是一種途徑協助人們從宏觀角度了解系統,包括了整體結構、模式及周期。相對于笛卡兒及其他人的還原論、哲學分析,它傾向整體主義。因為它關心的是整體及其各部分之間的關系。https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%B5%B1%E6%80%9D%E7%B6%AD
- 注2:習得性失助(或稱習得無助論、習得無助、習得無助感、無助學習理論、learned helplessness)為描述學習態度或心理疾患的心理學術語,主要用于實驗心理學。“習得性失助”可解釋為“經過某事后學習得來的”無助感,意謂著 一種被動的動物消極行為(也包括了人類行為),其中被動的因子占相當多數。https://zh.wikipedia.org/wiki/%E7%BF%92%E5%BE%97%E6%80%A7%E5%A4%B1%E5%8A%A9
- 注3:公地悲劇(Tragedy of the commons)是一種涉及個人利益與公共利益對資源分配有所沖突的社會陷阱。這個字起源于英國作家威廉·佛司特·洛伊(William Forster Lloyd)在 1833 年討論人口的著作中所使用的比喻。https://zh.wikipedia.org/wiki/%E5%85%AC%E5%9C%B0%E6%82%B2%E5%8A%87
- 注4:過度捕魚,又稱過度捕漁、過度捕撈、過漁,指捕漁活動將魚類資源降低到可接受的程度以下。其可以發生在大小在魚塘到大洋之間的任何水域。https://zh.wikipedia.org/wiki/%E9%81%8E%E5%BA%A6%E6%8D%95%E9%AD%9A
- 注5:Scrum 是一種敏捷軟件開發的方法學,用于迭代式增量軟件開發過程。Scrum 在英語是橄欖球運動中爭球的意思。雖然 Scrum 是為管理軟件開發項目而開發的,它同樣可以用于運行軟件維護團隊,或者作為計劃管理方法。Scrum 之間的合作稱為“Scrum of Scrums”。 https://zh.wikipedia.org/wiki/Scrum
- 注6:在工作與家庭不均衡的背后是一個“富者愈富”(Success to the Successful)的基模,兩個增強回路在爭奪一個共同的資源,工作和家庭在爭奪時間,越是表現出色的一方越可以爭得更多資源而更加出色,從而向一方 傾斜。因此,不打破這個模型(環路)無法改變現實。http://wiki.mbalib.com/wiki/%E3%80%8A%E7%AC%AC%E4%BA%94%E9%A1%B9%E4%BF%AE%E7%82%BC%E3%80%8B 還可以參考「馬太效應」:https://zh.wikipedia.org/wiki/%E9%A9%AC%E5%A4%AA%E6%95%88%E5%BA%94
- 注7:《彼得原理》(英語:Peter Principle)是管理學家勞倫斯·彼得(Laurence J. Peter)在 1969 年出版的一本同名書,里面提出的“彼得原理”是指:在組織或企業的等級制度中,人會因其某種特質或特殊技能,令他在被擢升到不能勝任的地步,相反變成組織 的障礙物(冗員)及負資產。《彼得原理》解釋了人力資源中的級際競爭,原理中帶有黑色幽默,但是也很現實。https://zh.wikipedia.org/wiki/%E5%BD%BC%E5%BE%97%E5%8E%9F%E7%90%86
- 注8:社會達爾文主義是將達爾文進化論中自然選擇的思想應用于人類社會的一種社會理論。最早提出這一思想的是英國哲學家、作家赫伯特·斯賓塞。https://zh.wikipedia.org/wiki/%E7%A4%BE%E4%BC%9A%E8%BE%BE%E5%B0%94%E6%96%87%E4%B8%BB%E4%B9%89
- 注9:邁達斯(古希臘語:Μ?δα?,又譯作“米達斯”、“彌達斯”),希臘神話中的弗里吉亞國王,故又稱“邁達斯王”或“邁達斯國王”,以巨富著稱;關于他點石成金的故事非常有名。https://zh.wikipedia.org/wiki/%E8%BF%88%E8%BE%BE%E6%96%AF </ul>
這看起來有些自私,不是嗎?然而也不是。對于動機,無論內在還是外在,無論故意還是偶然,都比較有力量。公地悲劇的每個參與人,或許完全沒有注意到他們自己在「公地」上的努力,常常是因為這種努力只有在悔之晚矣的時刻才能看到。
你的動機是什么?
沒有?好好想想。
你的真正動機是什么?
滑向低效
一個系統不僅抵制積極的改變,而且持續滑向更糟糕的效率,這種陷阱被稱之為滑向低效。
這種陷阱把人類思維的可憐傾向變成了信奉壞消息而非好消息。當一個系統所感受到的狀態糟于實際狀態時,滑向低效就發生了。隨著時間的推移,目標逐步被侵蝕,導致螺旋式下降。
這個陷阱經常出現在遺留代碼,不管你有沒有維護它的期望,隨著時間的推移,代碼質量會變得越來越低。遺留代碼所感受到的狀態(負責遺留項目的開 發人員的心境)要比真實狀態糟糕。因此對于質量維護的目標,將持續低于客觀現實(假定有這么一種衡量代碼質量的客觀方法)。當一個人的目標總是低于現實 時,對目標的侵蝕最有可能的就是產出了,從而導致越來越糟糕的代碼。
為什么遺留代碼所感受到的狀態要比客觀現實差呢?嗯,就從「遺留代碼」的名字開始,它已經將其定性為負面了。維護遺留代碼質量的目標,更傾向于 輾轉于「夠用即可」,隨著時間的推移,遺留會變成更多的遺留,對狀態的感受也漸行漸遠,「夠用即可」的認識和相關的維護努力也會如此。
當我們根據系統的當前狀態而非最佳狀態、或客觀的、務實的理想來預測時,這個陷阱就會出現。
你在軟件工程的哪個地方看到過滑向低效的情況發生?
Scrum【注5】中的沖刺預測會成為侵蝕目標的犧牲品。未能滿足你的沖刺目標?下一次少預測一點兒。仍然不能滿足你的目標?為什么不再少預測一點點呢?聽著很耳熟吧?
如果團隊陷入兌現承諾的負罪感,或當最后期限到來時會有懲罰措施出現時,這種趨勢就尤為普遍了。單純地更加努力工作是非常少有的解決方案,如果你想通過威脅來滿足需求,那么希望你有好運氣。
升級
系統陷阱的軍備競賽。如果你打我一拳,我就狠狠地打你一拳,我最好撐住自己、甚至給你更狠的反應。這種陷阱是你總比別人強一些。
有人可能認為,這種陷阱剛好與「滑向低效」相反,前者針對某個競爭系統所感受到的狀態,持續升級某種系統狀態。它可以是積極和消極的,取決于動機或可感受到的系統目標。
設想一下,系統目標是為了更有效地滿足客戶需求而非競賽。這種情況下的軍備競賽將是良性的。然而,如果「滿足客戶需求」意味著將成本降低到競賽 之下,那么在其它需求(比如質量、收益等)起作用之前,這種加強的反饋回路只能運行了。總之,勝人一籌會很快導致負面影響,因為指數級的改變從來不會繼 續。
這種陷阱經常見于軟件工程,尤其是當組織內部把競爭錯誤地當做動機的時候。
你曾經用你編寫的單元測試的數量來衡量其他人嗎?bug 被修復的數量、完成的故事、完成的代碼審查、或但愿沒有你編寫代碼的行數?你的團隊曾經根據你的速度標準和另一個團隊競爭嗎?那些「KPI」曾經被廣為宣傳,只是為了「激勵持續改善」或(更多的是)點名批評?當我們所有人被這樣一種方式衡量時,會怎樣呢?
這些衡量將要改善,就這么簡單!
它們將要不斷改善,直到你做了大量單元測試、大量 bug 修復、大量代碼審查、以及多得不可思議的代碼行數。恭喜你。
當你完成監測這些測量時,抽出一分鐘看看自己是否得到了收獲。記住,打算出門前,把燈關了。
由于我或多或少地夸大了的例子,當升級和另一個系統陷阱「尋求錯誤目標」結合時,將是危害最大的。甚至當目標相當有價值時,升級會很快搞壞你的系統。
富者愈富
富者愈富【注6】、貧者愈貧。這是對富者愈富的概括:在這個系統原型里,機會只屬于那些已經富有的人。這是一個增強反饋回路的例子,富有孕育著富有。
這就是你說的陷阱?確定這就是世界運行的方式?這不是等同于達爾文進化論嗎?這不是精英制度嗎?精英制度不好嗎?
不,不是這樣簡單,絕不。
你的組織自豪地把精英制度作為一種文化價值嗎?這意味著成功與特權、財富沒有關系,而與「宣揚的價值」有關。這對你有什么影響呢?
是什么在激勵著員工,或更重要地,是什么在激勵著員工貌似取得成功?如果當前過程中最重要的因素是表現出成功,那么它對你失敗的意愿有著怎樣的影響?它會怎樣影響你創新的能力(作為個人或組織)?
斯坦福大學心理學教授 Carol Dweck 出了一本優秀作品《MindSet》,她描述了增長心態(Growth Mindset)和固定心態(Fixed Mindset)的 區別。有著固定心態的個人,傾向于信奉基本素質是固定特質,比如智商或才能。然而,他們傾向于把時間用在盡量表現智商或才能上,而非主動開發這些特質。另 一方面,有著增長心態的個人,更信奉大腦和才能只是起點,可以通過專注和艱苦工作來持續開發。增長心態產生了對學習的熱愛、對失敗的恢復能力,這對于取得 偉大成就是不可或缺的。
你對精英制度培養的目標是哪種心態?
Linda Rising 認為,增長心態等同于「敏捷心態」(agile mindset),樂于失敗、適應并堅持持續改進,和固定心態不兼容。然而,我們目前的文化和組織,傳統上傾向于看重成功的出現,而非讓你到達成功的、骯臟、雜亂、易于失敗的道路。
這種敏捷的路線是擁抱失敗,因此當心你們對「富者愈富」的對待方式。
當然這不全是敏捷。富者愈富導致「彼得原理」【注7】,根據人們之前角色的績效而被晉升到不能勝任的新角色。如果有人把精英制度等同于達爾文進 化論,請提醒他們這里有個另外的名字,那就是「社會達爾文主義」【注8】,它被某些阿道夫·希特勒用于評判 20 世紀上半葉期間所有不愉快的事情。
將負擔轉嫁給干預者
將負擔轉嫁給干預者和上癮有很多共通之處。這種情況下的干預者是該問題的解決方案,如果解決方案為了維護本身而暗中破壞了系統功能,那么這種陷 阱就出現了。舉個酗酒的例子,真正解決戒掉酒癮的方法就是再喝一次。當第二天早上痛苦再次降臨時,只有喝更多的酒才能減輕痛苦。對于這個例子,酒就是解決 方案,一個真正糟糕的解決方案。
當我們審視上癮時,回憶偏倚(recall bias)讓我們想到了酒和毒品,但是同樣系統化的模型就在我們周圍,包括專注軟件開發的組織。我沒有暗示說,工作驅使你喝酒。
考慮修復 bug 的例子。你經常有個選擇:針對該故障打補丁、或找到該 bug 的潛在原因。快速的故障消除,經常是選擇了第一種方案,而留下了未解決的潛在原因。簡單地給 bug 打補丁,會導致代碼更加難以維護,相應地會產生更多的 bug,需要更多的補丁才能修復。這種螺旋式下降最終導致了不可維護軟件的悲劇:軟件成了針對軟件本身的、不明智解決方案的犧牲品。
一旦你注意到了這種模式,就能看到它出現在各個地方。下面是軟件驅動組織里的、一些將負擔轉嫁給干預者的例子。
你對什么上癮?切記,第一步是承認你存在問題。
打破規則
速度陷阱真的降低了速度,或它們鼓勵加速、隨之而來的是在攝像頭前面的急減速?部分預算真地扮演了消費的上限,或它們成了過度消費的目標?
「打破規則」描述了一種現象,規則讓某個系統處于扭曲的狀態,在缺乏規則時變得毫無意義。這通常可歸結為遵循規則條文而非規則精神。規則破壞者看起來好像在遵守規則,實際上在違反著規則。
讓我們考慮一種組織規則,它要求某個冗長的簽退過程被評估的時間,比完成的天數 x 要長。這將導致所有的努力都要屈從于這個簽退過程?這將導致很多工作量都被評估為 x-1 天?
開發團隊被設定了一個績效指標,在今年完成他們對 80% 沖刺的承諾。這個結果將導致更好的專注并增加對結果的關注嗎?為了達到該指標,團隊將故意(或下意識地)對他們的工作評估過高嗎?
如果「敏捷調查」表示著所有的用戶故事必須以「作為一個<角色>/我想要<活動>/以便于<商業價值>」 格式來撰寫,又會怎樣?這真的可以讓人們專注于用戶需求嗎?你真的能夠以「做為一臺 LDAP 服務器」開頭,寫一堆用戶故事?
你正在破壞著哪些規則?你的哪些規則正在被破壞?
尋求錯誤的目標
當你發現愚蠢的事情發生時,說明你遇到了破壞規則的問題,因為這是圍繞規則的一種方式。當你發現愚蠢的事情發生時,說明你遇到了錯誤目標的問題,因為「這關乎規則」。 ——Dana Meadows
</blockquote>邁達斯【注9】尋求了錯誤目標,他想成為巨富,但是設定了糟糕的目標,最終死去了。金子,但是死了。
![]()
當一個人朝著目標的過程通過間接測量而非目標本身時,「尋求錯誤目標」的陷阱常常會發生。對于邁達斯的例子,他對財富的追求被定義成了創造金子 的能力。最后,他把碰到的所有東西都變成了金子,這不一定讓你富有。對幸福的追求是另一個目標,易受這種陷阱的影響。比如,某人或許通過財富的間接測量來 追求幸福,然而追求財富讓你變得富有,卻常常不能讓你幸福。
當間接測量成為目標本身時,這種陷阱就出現了。我們經常在軟件開發中看到過,「價值」被機智地從客觀角度測量,因此我們求助于間接目標。當缺乏 價值的客觀測量時,我們或許選擇測量速度、或「被交付的故事點」。這是非常不明智的,因為速度與價值完全無關,因為它容易當成兒戲,尤其在團隊對于其增長 負有責任時。鼓勵速度增長,實際上會導致客戶可感知的價值減少,因為團隊把努力都聚焦在了創造價值的表現上、而非真正地創造價值。
軟件開發中,尋求錯誤目標的其它例子有:
就像傳統神話故事中的三個愿望一樣,系統有一個可怕的傾向,那就是準確地產出、或僅產出你要求他們產出的。要當心你讓它們所產出的。
</blockquote>總結
根據我自己做為軟件工程師的經歷,寫了這么長一篇文章,真地幫我理清了一些負面的系統原型。我很有興趣聽到你面對這些陷阱時的體會、以及你是如何克服它們的。你愿意分享你的體會嗎?
Part II 接著本文,并給出了一些答案。
</div>本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!