發表文章

每一年都會在軟體工程領域中出現新的趨勢,其中一些很快陷入困境,而另一些則從根本上顛覆了軟體的開發方式。 當任何一種創新成果帶著巨大的吸引力出現在我們面前時,人們會很快開始積極湧入,而這又會引導更多本打算旁觀的人參與其中。 每隔一段時間,又會出現一種不同於其他的創新 (有時候也表現為就有技術再復甦)。這種創新由其中的某一特定實現所驅動,以NoSQL浪潮為例,其就受到了MongoDB出現及快速崛起的重大推動。 這不是把列數據庫、鍵值存儲和其他多種數據存儲類型都混到NoSQL這個陣營了嗎?是的,但那個時候這種混淆就是現實,而且非常嚴重。每個人都高舉著NoSQL的旗幟,每個人都說他們離不開NoSQL,但實際上他們並沒有真正理解其中涵蓋的不同技術元素。對很多人來說,MongoDB實際上就是NoSQL。 如過這些組織能夠在做出技術選擇之前先拿點時間按部就班進行一番思考,則完全能漚避免這樣的折騰。 只要提出兩個主要問題,就足以合理評估眾多技術方案。但其中的挑戰在於要找到能負責任地回答這些問題的人,他們必須願意花時間回答這些問題,同時確保答案中不存在任何偏見。 問題一:我打算解決什麼問題? 如果沒有遇到某些特定問題,就不需要引入新的工具。而且,不要拿著解決方案反過來尋找問題,這是一種為了使用工具而使用工具的行為。換言之,如果不存在能夠證明新技術優於現有技術的具體需求,那麼就不要費力做這些沒必要的決策。 在這種情況下,我們不仿從最簡單的層面出發: 問題二:我放棄了什麼? 這個問題是更難回答的,因為我們必須對舊有/新的技術都要有很好的理解。有時候只有在實際利用新技術構建某些方案之後,我們才能理解該技術的真正內涵。或者,我們也可以找到那些曾在新技術投入過大量時間的實踐者並聽取他們的意見。 如果這兩種方法都不可行,那麼我們就真的需要考慮如何透過最小投資確定該工具是否具有價值。而且,如果進行了前期投資,又是否會增加撤銷計劃的難度? 人性總會把事情弄糟 我們必須記住,在嘗試以客觀中立的方式回答這些問題時,總會有人性因素跑出來作祟。為了有效評估技術,我們必須克服一系列認知偏見,下面僅舉幾例: * 從眾心理 – 每個人都聽過這種說法,但卻仍然很難擺脫出來。總之,請確保在選擇技術時,完全是因為它能夠解決您的實際需求,而非某些看似很牛的家伙也在做

何時使用primitive type與wrapper type?

技術人員在閱讀一些關於編碼效率的文章時,多少會看到要使用Java的primitive type或wrapper type之間的爭議。要求使用primitive type的原因不外乎是能夠盡可能的減少物件產生與管理時的系統資源overhead。例如如果服務需要處理大量的請求,而每個請求的處理過程中的數字或布林值都是對象的話,那麼影響到的資源使用確實可能是巨大的。所以問題是,我們在進行業務開發時使用的entity或DTO類中的字段究竟該使用primitive type或wrapper type呢? Wrapper class: java.lang.Integer 優點: * 允許null,因此在用戶複值時可以透過null來表示空白值、無值等字段的狀態。 * 以整數類來說,如果使用的值在-128到127之間的話,JVM使用的會是內存中的緩存對象而非新建對象,因此這個狀況下的overhead極低。 * Wrapper類中有包含多個便利方法,可以在lambda中使用,例如Integer::valueOf。 缺點: * 不可變性(immutability):因為warpper class的實體是不可變的,所以任何對值的變動都需要建立新對象。 * 因為所有數字都是對象,因此存在對象處理的overhead,所有數值計算都會較慢 Primitive type: int 優點: * 計算較快 缺點: * 所有未被指定的值都會被預設為0,這在業務代碼中進行處理時可能會造成混淆。例如:現在看到某自斷的值是0,那麼是用戶選擇了0,還是沒有進行任何選擇? 所以,wrappre所帶來的一個比較明顯的差異,實際上也是因為這個差異造成了他比較適合作為DTO自斷值的原因就是「它允許null」。因為在序列化過程中,我們可以透過JSON序列化框架的設定來決定是否輸出該值,以減少序列化後對象的字段數量,並告知API的使用方:現在確實沒有這個值,而非給予0之後要求使用方進行其他判斷。 例如以下這個類其中有一個SSN字段,分別使用了int與Integer: ```java class Person {   int SSN; } ``` ```java class Person {   Integer SSN; } ``` 在第一段代碼