-
Tell, Don't Ask
Web MVC 三層架構已盛行多年,因此在許多專案中經常可看到 VO, DTO 只有資料而沒有邏輯的物件,也稱為貧血模型(Anemic Domain Model)。然而這種設計並不符合物件導向的設計理念,因為它破壞了物件的封裝特性,使物件的內部資訊容易被外部濫用,提高與外部物件的耦合程度。Tell, Don’t Ask 軟體設計原則意旨在提醒開發者應盡量避免類似情形。
-
Java Lombok 教學與注意事項
Project Lombok 是很實用且被廣泛運用的語法糖 library,它可以減少許多樣板程式例如 getter, setter 等,我們只需幾個簡單的 annotation,例如 @Data,就能幫助我們省下大量重複的工作,讓開發者更專注於關鍵的邏輯,進而提高開發效率。但我認為 Lombok 也存在缺點,若過度使用 Lombok 可能導致問題,使程式碼難以維護。
-
如何寫出優秀的單元測試 (Best Practice)
單元測試已是軟體工程師必備的技能,但在我的經驗中,有些人寫的單元測試看起煞有其事,實際上卻沒測到重點,而且還容易因為重構而導致測試失敗,可說是為了測試而測試。這樣的測試不僅不會帶來好處,反而還使專案更不穩健,因此遵循測試的 Best Practice 是很重要的。本文將介紹 Java Unit Test 最佳實踐與案例,並提出許多人遭遇的盲點。
-
軟體設計原則 KISS (Keep it simple, stupid)
KISS (Keep It Simple, Stupid) 是軟體開發中常用的最佳實踐之一,指的是在開發或設計時應該保持簡單,避免使用過於複雜的程式碼。KISS 原則的目的是為了使軟體易於理解和維護,並且能夠減少軟體中的錯誤。
-
如何提高程式碼的可測試性 (Testability)
眾所皆知,寫單元測試有非常多好處,但有些主管會問,為什麼寫測試會讓工程師額外花這麼多時間?除了因為缺乏單元測試技術知識外,根本原因是產品程式碼的可測試性太低,導致工程師在撰寫測試時難以將精力放在正確的地方,甚至放棄撰寫測試。要寫出優秀的單元測試有一定的難度和門檻,關鍵在於如何提高程式碼的可測試性。
-
Java Jackson ObjectMapper 教學與注意事項
Jackson ObjectMapper 是 Java 中應用非常廣泛的序列化、反序列化的工具,它可以幫助我們簡單、快速將 Java 物件與 json 之間作轉換,就連 Spring Framework 將它作為預設轉換器。不過,一旦使用的人多,錯誤的寫法也就層出不窮,如果沒有按照正確做法,將很容易導致問題,本文將描述如何避免與改善。
-
Java SimpleDateFormat 教學與錯誤用法
開發 Java 專案時經常操作時間、日期與字串的互相轉換,最常見簡單的方式是使用 SimpleDateFormat,想必大家對它不陌生。雖然它簡單易用,如果沒有正確使用,在一般環境下使用通常不會出錯,但在高併發(Highly Concurrent)的環境下就可能會出現異常。
-
多此一舉! 不要這樣用 Java 8 Optional
Java 8 新加入了 Optional 類別,能省去繁瑣的 null check 流程,豐富的 API 也讓程式邏輯看起來更簡潔、易讀。但我卻看到了不少錯誤的用法,反而讓 Optional 顯得多此一舉。本篇探討這些錯誤的用法,以及如何正確使用。
-
軟體設計原則 DRY (Don't repeat yourself)
DRY (Don’t repeat yourself),是敏捷開發的核心設計原則之一。DRY 原則規定,對於每個知識點,系統中都只有一個明確而權威的表示。這個原則倡導單一事實來源(single source of truth) 的哲學,適用於所有的軟體開發工作,包含文件、設計、測試。但此原則常常被誤解,不少人認為只要兩個程式片段長得一樣就是違反了 DRY 原則。事實上,有些情況中的重複並不是一件壞事,甚至有些沒有重複的程式卻違反 DRY 原則。本文將探討 DRY 原則的運用情境。
-
使用 Log4j2 輸出 CSV 檔,並輕鬆解決 Excel 中文亂碼問題
我最近在 Java 專案中使用 Log4j2 做即時日誌並輸出 CSV,輸出完成後,文字編輯器打開一切正常,但以 Excel 開啟時卻出現亂碼,明明是 UTF-8,怎麼還會有亂碼呢? 查資料後才發現原來 CSV 的檔頭沒有帶著 BOM (byte-order mark) 導致。本文介紹兩種解決辦法。
-
軟體設計原則 YAGNI (You aren't gonna need it!)
YAGNI (You aren’t gonna need it!),是敏捷開發的核心設計原則之一。此原則指出,程式開發者應該在面臨確鑿的需求時,才實作相應的功能。換言之,就是不要實作那些現在用不到的東西,也不要因為未來可能需要的理由而事先實作。這樣做的目的是為了避免浪費時間和資源去開發最終可能永遠不會使用到的功能,同時也能使軟體的設計變得更加簡潔和易於維護。
-
Spring + Maven + IntelliJ 多環境 (Profile) 整合技巧
在 Spring 專案中,profile 是用於區分各種環境的,例如本機環境、開發環境、測試環境、正式環境等等。本文介紹一個透過 profile 來達成自動適應環境的開發與部署方式。此方法可以減少不必要的人工步驟,從開發到部署,透過指令就可以輕易完成。
-
分析 Spring 的依賴注入模式
依賴注入 (Dependency Injection, DI) 是 Spring 實現控制反轉概念的重要手段。Spring 提供了數種 DI patterns,其中最方便、最常用的是 field injection,它應該是許多人第一次寫 Spring 專案時所使用的 pattern,雖然這方式簡單易用,卻有不少缺點。
-
常見的 Java Interface 錯誤用法
在 Java 專案中,應該不少人看過或寫過只有一個實作(implementation)的介面(interface),並且以 interface-impl 的風格成對出現,如下圖的 FooImpl, BarImpl, ServiceImpl:
-
不建議使用 PowerMock 的理由
寫單元測試時常會使用 mocking framework,因為它能幫助我們輕鬆建立 mocked object,不必再為了單元測試而寫假物件,更容易對待測物件隔絕外部相依,進而降低寫單元測試的負擔。目前有許多主流 mocking framework,如最受歡迎的 Mockito,以及本篇文章的主角 — PowerMock。