2026/11/2

12-Factor App

12-Factor App 是 Cloud Based 軟體開發的方法。它最初由 Heroku 的共同創辦人 Adam Wiggins 於 2011 年提出,總結當時在該平台上開發與部署應用程式後所獲得的寶貴經驗。2010 年代,系統正在從傳統伺服器,轉向 PaaS 與 SaaS。Heroku 的工程團隊整理出這套規範,讓開發者能建構出更具 Scalability 及 Portability 易於維護的應用程式。

方法的目標:

  • 標準化

    以宣告方式 declarative,建立自動配置,減輕新的開發人員初次參與專案的時間與成本

  • 可移植性

    有clean contract 明確的定義,確認作業系統,並能提供在不同執行環境運作的最大彈性

  • 可部署在 cloud platforms

    適合部署在先進的雲端系統,減少伺服器與系統的管理問題

  • 持續部署

    減少開發與正式環境的差異,能夠持續部署,以達成 agility 最大化

  • scale up

    不需要改變工具、架構、開發環境,就能快速因應大流量

1. Codebase

One codebase tracked in revision control, many deploys

一份在 vevision control 管理的程式碼,可部署在多個執行環境

2. Dependencies

Explicitly declare and isolate dependencies

明確地宣告及隔離相依性

3. Config

Store config in the environment

在執行環境中儲存設定配置,不要寫在程式裡面

4. Backing services

Treat backing services as attached resources

把DB,Cache, MQ,SMTP 等等外部資源,透過 URI 的方式存取

5. Build, release, run

Strictly separate build and run stages

嚴格分離 Build, Release, Run 階段

  • build 是編譯成服務元件

  • release 是將元件發佈到 registry,提供給外部執行環境下載

  • run 是在執行環境取得元件,搭配部署設定執行該元件

6. Processes

Execute the app as one or more stateless processes

以一到多個無狀態程序執行app

7. Port binding

Export services via port binding

透過 service port binding 對外提供服務

8. Concurrency

Scale out via the process model

透過 process model 水平擴充

  • 每一個 service app 都是獨立的 process,可啟動多個 thread 分散 process 性能壓力

  • 同一個 service app 也可以啟動多個 instances

9. Disposability

Maximize robustness with fast startup and graceful shutdown

快速啟動/優雅終止 app,最大化系統穩定度

10. Dev/prod parity

Keep development, staging, and production as similar as possible

盡可能保持dev、pre-release、prod環境相同

11. Logs

Treat logs as event streams

將 logs 視為事件串流

  • 微服務應該建立統一的服務來管理日誌(ELK、Graylog、Cloudwatch...)

  • 每個運行的微服務都直接透過Stdout和Stderr來輸出日誌。開發時期透過console來查看時間排序下的Event log。正式環境,則是透過 log 管理服務,來收集、聚合、索引、分析這些Log

12. Admin processes

Run admin/management tasks as one-off processes

把維護/管理任務當作一次性process執行

  • 例如 db migration, db snapshot, schema/table更動,定期renew憑證等等

  • 把這些一次性作業寫成腳本或是Shell,當成一般程式來執行,也進到Git做版控

References

The Twelve-Factor App

[12 Factor原則簡介

2026/10/19

Harness Vibe Coding

Harness 這個詞,當作名詞時,最核心的意思是「束縛帶」、「馬具」或「控制、利用的工具」;當作動詞則是「駕馭」、「利用」。搭配了 Harness Engineering 以及 Harness Vibe Coding。就是透過 harness 這個單字的意思,描述一個 AI 工程的工具,需要在使用時,透過約束、引導、監控的方法,來完成工作。

AI 模型的程式生成能力非常強大、速度極快且不知疲倦,但如果放任不管,它可能會朝錯誤的方向亂跑、產生幻覺或寫出無法維護的程式碼。Harness 就是一套用來約束、引導、監控 AI 的機制與工具系統(例如:架構約束、自動化測試、型別檢查、CI/CD 迴圈、特定的 Context 規範)

Vibe Coding 最初是指人們只靠著跟 AI 對話、憑感覺指揮 AI 生成程式碼,不管底層細節。但這種方法如果要做大型、長久維護的專案,就會遇到瓶頸。這時就會需要 Harness。

實踐 Harness Engineering 可以從以下四個層面著手:

1. 上下文與邊界工程(Context & Boundary Engineering)

AI 之所以會寫出不符合架構的程式碼,通常是因為它「看不全」或「看錯了」全貌。Harness 的第一步是為 AI 提供絕對清晰的地圖與邊界:

  • 專用導航文件(如 AGENTS.md 或 .cursorrules):在專案根目錄建立專門給 AI 閱讀的說明書,明確規定專案採用的架構(例如:嚴禁直接在 Controller 呼叫資料庫等)。

  • 限制修改範圍(File-level Scoping):在執行 AI Agent 時,明確限制它只能修改特定的目錄或檔案,防止它不小心覆蓋了核心安全性或基礎設定。

2. 高頻自動化回饋迴圈(High-Frequency Feedback Loops)

AI 生成程式碼後,最怕的是「靜默失敗」或引入隱含的邏輯錯誤。Harness 必須建立一套能讓 AI 「自我修正」的閉環系統:

  • 嚴格的型別系統與編譯檢查:採用強型別語言或完整的 TypeScript/JSDoc/Java 泛型約束。當 AI 寫出型別不符的程式碼時,編譯器錯誤訊息(Error Traceback)會立刻被擷取並丟回給 AI,讓它在下一輪對話中自我修復。

  • 單元測試與整合測試防線:在 AI 介入前,確保專案具備高覆蓋率的測試。當 AI 完成修改後,自動執行測試。如果測試失敗,測試報告就是回饋給 AI 的精確導引。

  • Linter 與 Static Analysis 門神:Linter(代碼檢查工具)是一個在軟體開發中用來自動分析原始碼的工具。它不需要實際執行程式,就能掃描程式碼並標記出潛在的錯誤、語法問題、安全漏洞以及不符合規範的風格寫法。透過 ESLint、Checkstyle、SonarQube 等靜態檢查工具,在程式碼落地前就攔截掉潛在的效能陷阱或語法不規範。

3. 沙盒與執行權限隔離(Sandboxing & Least Privilege)

當你使用更具自主性的 AI Agent(能自己執行 terminal 指令、安裝套件)時,Harness 的角色就變成了「安全沙盒」:

  • 容器化執行環境:將 AI 執行的終端機指令關在 Docker 容器或虛擬機中,避免 AI 誤下一行 rm -rf / 或修改到主機的敏感設定。

  • 最小權限原則:限制 AI Agent 的 API Key 或工具權限(例如:唯讀存取生產環境資料庫、禁止直接推送到主分支 main/master)。

4. 人類閘道與語意審查(Human-in-the-Loop & Semantic Gatekeeping)

Harness 不僅是自動化工具,還包含人類工程師的防禦策略:

  • 原子化 PR 審查(Atomic Pull Requests):強迫 AI 一次只做一件小事(例如「只修復這個登入驗證 Bug」或「只實作這個特定的 DTO 轉換」),不要讓 AI 一次修改幾十個檔案,這會大幅增加人類審查(Code Review)的盲點。

  • 關注語意而非語法:人類工程師在審查 AI 產出的程式碼時,可以完全不用檢查語法(因為 Harness 已經過編譯與測試把關),而是專注於業務邏輯是否正確、邊界條件(Edge Cases)是否考慮周全。

傳統的軟體工程是「人寫程式、機器執行」;而在導入 AI 後的軟體工程,人類的職責正在轉變為 Harness Architect,不需要手動敲每一行程式碼,而是透過建立嚴密的測試、型別、規範與回饋迴圈,讓 AI 在這條高速公路上狂飆的同時,永遠不會翻車。

2026/10/12

JEP 512 Compact Source Files and Instance Main Methods

java 的第一個範例程式 HelloWorld 必須要這樣寫,但初學者不能理解,為什麼一定要寫 class,main method 一定要宣告 public static void,也必須要加上字串陣列參數。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

自 JDK 21 開始,就有幾個簡化入門程式的 preview 功能 JEP,然後到了 JDK 25,正式 final 了 JEP 512。

主要的改動是,可以不寫 class,可以簡寫 main 為 instance method,也就是不需要宣告 public static void

JEP 512 核心功能

Compact Source Files

可以不寫 class

public static void main(String[] args) {
    System.out.println("Hello, world!");
}

Instance Main Methods

可以去掉 main method 的宣告

void main() {
    System.out.println("Hello, world!");
}

支援直接執行

傳統的 java 程式,必須要先編譯 javac HelloWorld.java 為 HelloWorld.class,然後才能執行 java HelloWorld

現在可以直接執行 HelloWorld.java

java HelloWorld.java

Summary

這些功能,並不是 Java 的常態。而僅只是為了讓初學者用類似 python 的腳本式語言的方式,學習並入門 Java。主要用在簡短的教學及範例程式。如果是大型正式的專案,還是不適合使用。

2026/9/14

JEP 467 Markdown Documentation Comments

JEP 467 Markdown Documentation Comments

自 JDK 23 開始,javadoc 支援在每一行 javadoc 中,以 /// 開頭的方式,標記為markdown 格式的 javadoc,這種方式取代舊的 /** **/ ,並支援 markdown 語法。

markdown 是簡化的 html,以往在 javadoc,需要用大量的 html tag,標記為

,

    , ,現在支援 markdown 語法的 標題、列表、代碼塊、連結、粗體/斜體,讓 javadoc 的內容更精簡。

    新舊兩種註解寫法是同時支援的。新的 markdown,除了比較簡潔以外,解決了傳統的 javadoc 使用 html,太難寫,需要寫很多 html tag 的問題,在查看 code 裡面的註解時,markdown 的可讀性明顯比 html 高。

    支援的 markdown 語法

    • 粗體,斜體文字

    • 段落與換行

    • 有序及無序的列表 list

    • 程式碼

    • 標題

    • 連結

    • 表格

    markdown javadoc 範例

        /// 這是使用 Markdown 格式的註釋。
        ///
        /// # 範例功能
        /// * 使用 **Highlight** 語法。
        ///
        /// # 程式區塊:
        /// ```java
        /// test("param");
        /// ```
        ///
        /// # 列表
        /// 1. 項目1
        /// 2. 項目2
        /// 3. 項目3
        ///
        /// # 連結 [google]("https://www.google.com")
        /// * 連結
        /// - 模組 [java.base/]
        /// - 套件 [java.util]
        /// - 類別 [String]
        /// - 欄位 [String#CASE_INSENSITIVE_ORDER]
        /// - 方法 [String#chars()]
        /// - 同一類別其他方法: [equals][#equals(Object)]
        ///
        /// # 表格
        ///
        /// | Latin | Greek |
        /// |-------|-------|
        /// | a     | alpha |
        /// | b     | beta  |
        /// | c     | gamma |
        ///
        /// @param param1 參數
        /// @return 回傳值

2026/9/7

SSOT Single Source of Truth

單一真理來源、唯一事實來源。資訊系統架構中的一個核心概念。其核心目標在於確保組織內的每個人、每個系統,在需要特定數據時,都參考同一個來源,從而避免數據不一致導致的決策錯誤。

這樣做可以確保:

  • 所有資訊的一致性和準確性

  • 減少重複數據和資訊衝突

  • 方便查找與更新

  • 簡化備份、遷移和共享流程

  • 促進團隊協作與溝通

SSOT 並不是指將「所有數據」都存在同一個資料庫中,而是指對於某個特定的數據點(例如:客戶地址、產品價格、庫存數量),在整個系統中只有一個權威的來源(Master Copy)。

在 IT 領域的應用意義

1. 確保數據一致性 (Data Consistency)

在大型 IT 架構中,多個系統(如 ERP、CRM、電商網站)往往會共用相同的數據。若沒有 SSOT,當客戶修改地址時,若只更新了 CRM 而沒更新 ERP,就會導致出貨錯誤。實施 SSOT 後,所有系統都會向「客戶主資料庫」看齊。

2. 降低數據冗餘與維護成本

重複的數據存儲不僅浪費空間,更增加了維護難度。透過 SSOT,開發人員不需要編寫複雜的邏輯來比對多個資料庫之間的差異,簡化了系統整合的複雜度。

3. 提升決策與分析的準確性

對於商業智慧(BI)與大數據分析而言,SSOT 是基礎。如果財務部門和銷售部門提供的營收報表數據對不起來(可能因為計算邏輯或數據來源不同),管理層將難以做出正確判斷。SSOT 確保了「數據來源一致」。

4. 加速開發與自動化

在 DevOps 或現代軟體開發中,SSOT 的概念也被應用於:

  • Infrastructure as Code (IaC): 例如 Git 就是基礎設施配置的 SSOT。

  • API 驅動架構: 透過統一的 API 接口存取權威數據,避免直接對原始資料庫進行多點讀寫。

實施 SSOT 的挑戰

雖然 SSOT 理想上很完美,但在實際運作中常遇到以下困難:

  • 跨部門溝通: 定義「誰才是權威來源」往往涉及組織權責分配。

  • 系統效能: 若所有系統都即時請求同一個數據源,可能造成效能瓶頸(通常透過緩存同步機制解決)。

  • 舊系統轉型: 整合缺乏標準接口的舊有系統(Legacy Systems)需要極大成本。