首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

演化架構與緊急設計(一):代碼即設計——表達性與抽象風格的深度探討

     編輯:Java 相關知識

本系列開篇確立核心觀點:**軟件設計的最終成果是完整的源代碼**。Jack Reeves 1992 年經典論文《What is Software Design?》指出:傳統工程交付「設計文檔」,製造由他人執行;軟件工程交付「源代碼」,編譯器/部署管線即製造團隊,構建成本趨近零。因此:

  • UML、白板圖、文檔僅是輔助思考工具,**非設計本身**
  • 代碼可讀性 = 設計可讀性,表達性直接決定模式發現難易度
  • 決策越晚越好(最後責任時刻),因上下文知識隨時間單調遞增

表達性對比:同一模式的三種語言實現

場景:工作單元模式——事務邊界管理樣板代碼。

Java 版(Command 模式 + 匿名內部類)

public void wrapInTransaction(Command c) {
    setupDataInfrastructure();
    try {
        c.execute();
        completeTransaction();
    } catch (RuntimeException ex) {
        rollbackTransaction();
        throw ex;
    } finally { cleanUp(); }
}

public void addOrderFrom(final ShoppingCart cart, final String userName, final Order order) {
    wrapInTransaction(new Command() {
        public void execute() {
            add(order, userKeyBasedOn(userName));
            addLineItemsFrom(cart, order.getOrderKey());
        }
    });
}

噪音:`final` 參數傳遞、匿名類結構、Command 接口儀式。

Groovy 版(閉包原生支援)

def wrapInTransaction(command) {
    setupDataInfrastructure()
    try {
        command()
        completeTransaction()
    } catch (RuntimeException ex) {
        rollbackTransaction()
        throw ex
    } finally { cleanUp() }
}

def addOrderFrom(cart, userName, order) {
    wrapInTransaction {
        add order, userKeyBasedOn(userName)
        addLineItemsFrom cart, order.orderKey
    }
}

Groovy 閉包 `{ ... }` 直接實現 Command 模式,無額外類型儀式。

Ruby/JRuby 版(yield 關鍵字)

def wrap_in_transaction
  setup_data_infrastructure
  begin
    yield
    complete_transaction
  rescue
    rollback_transaction
    raise
  ensure
    cleanup
  end
end

def add_order_from
  wrap_in_transaction do
    add order, user_key_based_on(user_name)
    add_line_items_from cart, order.order_key
  end
end

Ruby 方法可隱式接收代碼塊,`yield` 執行之——語言內建模式支援,零儀式。

框架即模式集合:好的框架從實戰中來

  • Hibernate `doInTransaction` ≒ 上述 `wrapInTransaction`
  • Spring `TransactionTemplate`、JPA `EntityManager` 同源
  • 象牙塔框架(如 JSF 自定義渲染管道)解決不存在的問題,增加認知負荷

抽象風格的突圍:Antiobject 思維

長期單一語言(如 Java OO)形成「金錘子」思維:所有問題皆為「物件+可變狀態+繼承」。

案例:Pac-Man 鬼魂追蹤算法(1980 年代硬體極限)

傳統 OO 建模:Pac-Man、Ghost 為物件,需計算雙方座標距離 → 運算力不足。

Antiobject 反向建模:將智能內嵌迷宮格子(背景對象)。

  • 每格擁有「Pac-Man 氣味值」:佔據格=最大值,相鄰格遞減 1,時間衰減
  • Ghost 行為極簡:隨機遊走 → 嗅到氣味 → 向氣味增強方向移動
  • 副作用:Ghost 無法攔截(只知 Pac-Man 曾在哪裡),但極低算力下可運行

Pac-Man 迷宮氣味擴散示意圖

函數式語言的抽象風格差異

維度Java (OO)Scala/Clojure (函數式)
預設數據結構 可變 不可變
併發模型 鎖/同步 不可變數據 + STM/Actors
抽象單元 類/介面 函數/高階函數
擴展機制 繼承/組合 組合/型別類/多方法

實踐啟示

  1. 選擇表達性強的語言/方言:Groovy、Scala、Kotlin、JRuby 可在 JVM 內混用,降低模式發現門檻
  2. 警惕框架的「毒販模式」:繼承框架基類(如 `ActionForm`)導致領域模型耦合框架 → 改用組合/適配器
  3. 重構時嘗試改變抽象風格:遇到極難重構點,問自己「能否建模背景而非前景?」
  4. 緊急設計 = 讓代碼引領設計:在「最後責任時刻」根據實際代碼結構提取模式,而非預先規劃

下一期將實戰示範:如何在代碼庫中發現、度量、提取慣用模式——指標驅動重構、結構重複識別、參數處理模式抽取。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved