貨物崇拜編程

  • 2020 年 2 月 10 日
  • 筆記

讀到這個標題,多數人會有疑惑,什麼是貨物崇拜編程,其實最根本的問題可能是什麼是貨物崇拜。想要了解這些就不得不說貨物崇拜(Cargo Cults,又譯貨物運動)的起源

第二次世界大戰太平洋戰爭時,美軍於塔納島建立一臨時基地。當時島上的原住民看見美軍於「大鐵船」(軍艦)內出來,皆覺得十分驚訝;他們也看到,有一些「大鐵鳥」(軍用飛機)運送穿著美軍軍服的人及許多物資。這些原住民看見這種情況均感到很驚訝,並覺得這些「大鐵船」及「大鐵鳥」十分厲害。加上美軍也提供部分物資給原住民,而這些物資對原住民來說十分有用,結果這些原住民將美軍當作神。 第二次世界大戰結束後,美軍離開塔納島,只留下一些美軍軍服及一些貨物。塔納島原住民便認為這些貨物具有神奇力量,又相信「神」(美軍)他日會回來並帶來更多貨物,使他們展開一個幸福新時代。但是美軍當然再也沒有回來塔納島,因此這些原住民便自己發展出一套敬拜儀式,崇拜美軍軍服及貨物;表現形式是原住民會穿著美軍軍服、升起美國國旗,圖騰則是木刻的飛機。

貨物崇拜編程則是上面的貨物崇拜的引申,維基百科對其定義如下

貨物崇拜編程(Cargo Cult Programming)是一種電腦程式設計中的反模式,其特徵為不明就裡地、儀式性地使用程式碼或程式架構。貨物崇拜編程通常是程式設計師既沒理解他要解決的bug、也沒理解表面上的解決方案的典型表現。

現象

  • 從網路上看到一些 看似有道理卻不起作用的內容
  • 為了用設計模式而用設計模式等刻意使用
  • 複製Stack Overflow上的內容,只要運行OK即可

這裡以程式碼為例,列舉幾處違例

設置變數為null 釋放記憶體

可能很多人都聽過,類似手動設置變數為null,可以釋放記憶體,緩解記憶體壓力。於是就有人奉其為金科玉律,寫出了類似下面的程式碼

public class ViewHolder {        private View view;        private String message = "message";            public ViewHolder(View view) {            this.view = view;        }            public void clean() {            //解除引用關係,釋放記憶體            view = null;            message = null;        }    }  

上面的程式碼

  • 我們在clean方法中,手動設置view和message為null以期待可以釋放記憶體
  • 由於Java是自動垃圾回收,只要ViewHolder示例不被持有,view就可以釋放,view = null顯然是畫蛇添足
  • 更複雜的情況,message對應的字元串內容回收,還需要考慮字元串常量池的存在。message = null無法釋放字元串內容

使用弱引用防止記憶體泄露

同樣,很多人都聽說過 弱引用(WeakReference) ,它可以避免記憶體泄露,於是寫出了下面的程式碼

private void initWebView() {            try {                //使用弱引用防止程式webview導致記憶體泄漏                webView = new WebView(new WeakReference<Context>(this).get());                ....            } catch (Exception e) {                e.printStackTrace();            }        }  

上面的程式碼

  • 僅僅聽說了弱引用,但是不知道強引用,更不知道他們阻止GC回收的能力
  • WebView構造方法接收強引用的Context,new WeakReference<Context>(this)試圖構造一個Context的弱引用,但是new WeakReference<Context>(this).get()又從構建的弱引用中得出了原始的強引用
  • 上面的程式碼,只會是事與願違。

處理SSLError引發安全問題

@Override        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){      handler.proceed();    }  

上面的程式碼是Webview載入遇到SSL證書問題出錯時的回調,網上很多人告訴我們,像上面的方式處理就能解決網頁載入出錯的問題,殊不知這回引發更大的風險漏洞問題。

貨物崇拜的問題

  • 不熟悉內部原理,無法預期會發生什麼,這是很危險的

易出現人群

  • 新手或者經驗不足的人,對很多東西和技術不熟悉
  • 缺乏思考,思想懶惰的人

如何避免

如下,簡單談一些我認為能夠規避貨物崇拜編程的方式與方法

自身學習和思考,懷疑

  • 這是從內部驅動的解決方法,通過學習,我們可以把對一項技術的掌握從0變為1,進而變成100。在這個過程中,我們自然能規避那些貨物崇拜的問題。
  • 保持思考,切忌懶惰,對於技術和程式碼,我們在會使用的情況下,更要研究和思考並了解其內部的機制和原理。
  • 保持懷疑,科學精神的精髓就是「懷疑」,在既不能證實也不能證偽的情況下那就存疑

結對編程與程式碼審核

  • 這是外部驅動的解決方法
  • 找一個有經驗的人來結對編程,或程式碼審核,能夠在程式碼上線之前發現潛在的問題並更正。

拒絕貨物崇拜編程,學習,思考,懷疑。

References