在昨日介紹完Legacy Code之後,
總會先有人撰寫,
才能製造出Legacy Code,
而這往往都有著許多先決條件,
從源頭開始解決也不為是一種好方式。
而這些源頭之一就是反面設計,
在解決之前我們先來仔細認識一下,
何謂反面設計
指的是在實踐中經常出現但又低效或是有待優化的設計模式,是用來解決問題的帶有共同性的不良方法。
它們已經經過研究並分類,以防止日後重蹈覆轍,並能在研發尚未投產的系統時辨認出來。
主要是因為《AntiPatterns》這本書而被推廣,但不只是軟體設計,
裡面也有組織結構、專案管理、軟體工程等等
就是之前軟體開發方法論中提到的幾個重要類別
甚至就算是其他類別的內容,也常常可以推廣到其他方面。
筆者這邊重點描述分析癱瘓(Analysis Paralysis)。
每一個公司都有著組織架構,
而在反面設計裡也有提到很多有關架構的案例,
最容易影響效能並且很常遇到的事情就是
分析癱瘓(Analysis Paralysis)
最為常見的就是某一階段有著過於多餘的事物卡著。
起始的分析、開始行動的動機、訂下一個決策的力道、多個團隊中的交接等等。
過度分析:團隊成員花費大量時間和精力進行分析,討論各種可能的方案,但不願意做出最終決策。
缺乏行動:分析癱瘓的特點是缺乏行動。團隊可能陷入無休止的分析中,但卻無法實際開始工作。
僵化的決策過程:即使已經有足夠的信息來支持一個決策,團隊仍然拖延不決,因為他們擔心錯誤。
過度的文件和報告:為了支持分析,團隊可能創建大量的文檔和報告,但這些文件可能對實際開發工作沒有實質幫助。
決策困難:分析癱瘓可能是由於害怕犯錯或過度風險管理而引起的,團隊成員可能難以選擇最佳的解決方案。
整理看下來,可以看出來
分析癱瘓(Analysis Paralysis)
最主要的根結點就是害怕。
而在也往往對於新人來說,
最容易產生的情緒,
筆者在很多狀況下也很容易犯錯,
也很怕犯錯,
舉一個筆者曾經出現過的決策困難作為例子。
筆者有時候會替公司Refactoring一些特別的程式碼,
其中有發現Redis存取常常四散各地,
可又有一個叫做RedisServer的class。
以RedisServer以這種名稱來說,
通常會是集中管理有關Redis的各種function。
筆者覺得很奇怪,
整理過後發現
RedisServer是拿來集中的沒錯,
在建構子是可以傳入DB的,
但在裡面有寫死連線字串與DB。
導致如果要連線去其他台DB就要到處寫,
這是其一,
彈性被大幅縮減。
其二這個class被寫成Abstraction,
並且function寫成protected,
導致其他專案或class明明要存取一樣的地方,
那麼要使用這個class,
就只剩下一條路,
繼承並使用,
這樣就只能限定為固定的連線字串與DB。
這樣因為無法繼承或不想繼承,
導致四散各地的重複程式。
反過來說,
這個方式也有好處。
其一只能繼承的優點,
如果建構子宣告的參數是static,
可以用作pool的限制,
這樣可以有效的控制,
但前提是這個宣告是static,
那他就可以透過此來限制,
避免pool不夠,
並且如果想貫徹不給人改DB,
就不要在建構子傳入DB。
其二建構子可以傳入DB
筆者推論是為了可以改DB,
但由取名為init的function卡著,
導致根本沒有辦法有所彈性,
會只能限制住固定的狀況。
那麼筆者推測這個程式碼可能有兩個方向
如果要使用Redis就必須繼承,這樣可以限制好pool的控制。
如果要使用Redis就宣告並傳入DB,這樣可以保持好彈性。
那麼解釋完這一塊,
依現狀來說,
可以看到這個程式出現了抽象倒置(Abstraction inversion),
導致需要重複繼承去實現才能使用。
而後人為了解決使用了複製黏貼編程(Copy Paste Programming)。
這時候筆者就陷入了決策困難的類似境地,
整個心慌慌,
滿腦子都在想。
為什麼要使用抽象,明明並不需要重複實現?
為什麼要限縮他的權限,是基於什麼原因不想給人用?
最主要的可能是為了分清楚,但現在反而混淆了。
那麼從思考面來說,
Redis的定義並沒有需要延伸的概念,
反而提升的相依性,
而且由於繼承的話建構子不會繼承,
彈性大幅縮減。
所以不論是從程式或是思考來說,
這一個程式都是有所問題的。
可以看的出來,
因為以前的程式,
也就是Legacy Code,
放到現在來看能看出反面設計,
進而造成現在的延伸出其他決策困難,
這就是以個人的角度很常遇到的決策困難。
而這一些問題,
在正確的運用一些方式會能解決。
最常見的方式就是有決策者。
把以上遇到的問題提供給決策者,
讓決策者引導下指令,
那麼程式自然會呈現一致性。
但反過來說,決策者這個職位就會是耦合點,
基於公司性質會有各種方式,
不論是加重級別讓決策者可以負全責或是降低級別出現小主管等等都是方式。
畢竟水能載舟,
各位可以看到很多狀況
當然也有很多狀況是決策者所造成的。
任何能夠解決的方式都是方式,
但好方式裡面不會通常有特別極端的要求,
任一種極端往往會容易孳生反面設計。
---筆者推薦
筆者也很喜歡
帕金森瑣碎定律(Parkinson's Law of Triviality),
總會覺得荒唐又現實。
維基百科上的案例
西里爾·諾斯古德·帕金森於1956年的著作《帕金森定理,以及其他在管理上的研究》(Parkinson's law, and other studies in administration)中首次提出這個論點。 在第三章,《高昂的價格,或興趣消失的平衡點》中,帕金森描述了一個虛構的財政議會中討論的三項議題:第一項為搭建價值一千萬英鎊的反應爐,第二項為價值350英鎊的員工自行車棚,第三項為每年21英鎊為聯合福利議會茶店的提案。
一千萬英鎊的核反應爐在數額和技術含量上都高高在上遙不可及,在兩分半的討論之後便通過了。一名議會成員提出了完全不同的計劃,然而無人願意放棄議會取得的進展而響應寥寥,另一位熟稔該議題的成員略有擔憂,然而他覺得無法向議會的其他成員解釋清楚,最終作罷。
自行車棚的議題則處於所有人理解範圍之內,並有豐富人生經驗予以支撐意見,議會成員Softleigh先生表示鋁製棚頂價格高昂,應使用石棉。Holdfast先生提議使用鍍鋅鐵,Daring先生則對自行車棚是否必要表示質疑。Holdfast表示反對。辯論自此拉開帷幕,350英鎊的自行車棚。討論繼續。在經過45分鐘的討論,並得出有可能節省50英鎊的結果之後,議會成員帶著完成使命的成就感紛紛坐回原位。
帕金森繼續描寫第三項議題:「也許有些成員無法區分鋁製棚頂或石棉棚頂,但是所有人都了解咖啡-它是什麼,應該如何做,該在哪買-以及到底該不該買。這項議題將會占用議會成員一小時加一刻的時間,然而由於時間關係,會議結束時議員要求會議秘書提供更多信息,同時將此項議題的決定留待下次議會處理。」
推薦閱讀---筆者其實也還沒閱讀完,各位對這個有興趣,
筆者又解釋的過於粗略可以看看各位前輩所撰寫的
反面模式(Anti-pattern) --- 在說有多少模式,與概略解釋
https://topic.alibabacloud.com/tc/a/anti-pattern_8_8_32212712.html
反面模式
https://www.wikiwand.com/zh-tw/%E5%8F%8D%E9%9D%A2%E6%A8%A1%E5%BC%8F
閱讀心得:軟體測試的反面模式(anti-patterns)
https://medium.com/%E5%BE%8C%E7%AB%AF%E6%96%B0%E6%89%8B%E6%9D%91/review-software-testing-anti-patterns-35c9b422dc4e
Antipatterns
https://deviq.com/antipatterns/antipatterns-overview
Software Testing Anti-patterns
https://blog.codepipes.com/testing/software-testing-antipatterns.html
List and Gist of Antipatterns for Agile
https://www.linkedin.com/pulse/list-gist-antipatterns-agile-noorul-ameen-a
What Is an Anti-pattern?
https://www.baeldung.com/cs/anti-patterns
GOF相關的紀錄
[GoF] 物件導向程式設計邏輯
https://pjchender.dev/pattern/design-oop/
如果不反感中國用語
万字详解 GoF 23 种设计模式(多图、思维导图、模式对比),让你一文全面理解-本文为CSDN博主「enjoy编程」的原创文章
https://blog.csdn.net/penriver/article/details/118571991
版权声明:本文为CSDN博主「enjoy编程」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
使用 Go 實現 GoF 的 23 種設計模式(一)
https://www.readfog.com/a/1632288404812173312
https://learnku.com/docs/php-design-patterns/2018/anti-pattern/1526