01

中介軟體與分散式物件的核心精神

中介軟體提供更高層次的程式抽象,藏起底層異質性,讓互通與可攜變得可能。

先讀原文開場,旁邊就是白話

這是一本英文書。左邊放原文、右邊放白話導讀——你既讀得懂,也順手碰了原文。

原文 · 分散式物件與元件 335 8 DISTRIBUTED OBJECTS AND COMPONENTS 8. 4 From objects to components 8. 5 Case studies: Enterprise JavaBeans and Fractal 8. 6 Summary A complete middleware solution must present a higher-level programming abstraction as well as abstracting over the underlying complexities involved in distributed systems.
白話導讀

中介軟體提供更高層次的程式抽象,藏起底層異質性,讓互通與可攜變得可能。

中介軟體在忙什麼

中介軟體提供更高層次的程式抽象,藏起底層異質性,讓互通與可攜變得可能。

STEP 1

深度探秘

中介軟體到底夾在哪兩層之間

中介軟體是「夾心餅乾的中間層」

一個完整的分散式系統,底層是各種異質的硬體、作業系統與網路;上層是你想寫的應用程式。問題是:底層長得五花八門,你的程式不該被這些細節綁死。

中介軟體 (middleware) 就是夾在中間那層,它有兩個任務:

  • 提供更高層次的程式抽象,讓你寫分散式程式時不必每次都從 socket、封包打包開始。
  • 透過分層 (layering) 把底層異質性藏起來,促進互通 (interoperability)可攜 (portability)

互通=不同實作之間能彼此溝通;可攜=同一份程式能搬到不同平台跑。

本章聚焦兩種最重要的中介軟體風格:分散式物件 (distributed objects)元件 (components)

💡
關鍵

中介軟體提供高層抽象並隱藏底層異質性,讓分散式程式好寫又能跨平台。

STEP 2

生活妙喻

中介軟體就像國際會議的同步口譯

同步口譯員的比喻

想像一場聯合國會議,與會者講英文、法文、中文、阿拉伯文(這就是異質的底層平台)。如果每個人都要學會其他所有語言才能開會,根本辦不成事。

口譯員坐在中間,你只要對著麥克風講母語,對方就能用他的母語聽到——你完全不用管翻譯怎麼運作。

  • 口譯員 = 中介軟體
  • 「對著麥克風講母語」= 高層程式抽象
  • 「不用學其他語言」= 隱藏異質性
  • 「大家都能參與會議」= 互通與可攜
flowchart TD
  A[應用程式] --> B[中介軟體 高層抽象]
  B --> C[作業系統與網路 異質底層]
  B --> D[隱藏異質性 促進互通與可攜]
💡
關鍵

中介軟體像同步口譯,讓你只講母語就能和異質平台溝通。

STEP 3

實用超能力

為什麼物件導向特別適合分散式

物件導向的三個好處,恰好對症下藥

分散式物件之所以受歡迎,是因為物件導向的特質剛好解決分散式的難題:

物件導向特質 帶來的好處
封裝 (encapsulation) 把內部實作包起來,天生適合「跨機器只露出介面」
資料抽象 (data abstraction) 規格與實作乾淨分離,呼叫方只看介面,不管對方用什麼語言或作業系統
動態與可擴充 可以引入新物件,或用相容物件替換舊物件

真實情境:你在寫一個跨公司的訂單系統,對方用 C++、你用 Java。只要雙方同意一份「介面」,你呼叫 placeOrder() 時根本不用知道對方是什麼語言寫的——這就是封裝與資料抽象的威力。

代表性的分散式物件中介軟體包括 Java RMICORBA

💡
關鍵

封裝與資料抽象讓呼叫方只面對介面,這正是分散式程式最需要的乾淨邊界。

🔆
生活妙喻:中介軟體 (middleware) ≈ 聯合國會議的同步口譯員

你只講母語、對著麥克風,口譯員把訊息翻給講其他語言的人;你不用學任何外語,就像程式不用管底層平台差異。

🔆
生活妙喻:資料抽象 (data abstraction) ≈ 餐廳的菜單

你看菜單點菜(介面)就好,廚房用瓦斯爐還是電磁爐、廚師是誰(實作細節)你不必知道也不會影響點餐。

本節字彙

中介軟體 (middleware)
夾在應用程式與底層作業系統/網路之間的軟體層,負責提供高層抽象並隱藏異質性。
🧠 middle=中間,ware=軟體,就是「中間那層軟體」。
互通 (interoperability)
不同實作、不同平台寫的系統之間能夠正確地彼此溝通。
🧠 inter=彼此之間,operate=運作,彼此都能運作就是互通。
封裝 (encapsulation)
把物件的內部實作包覆起來,外界只能透過介面互動,看不到內部細節。
🧠 encapsulate=裝進膠囊,吃膠囊不會看到裡面的粉。
某公司想讓用 Java 寫的訂單服務和用 C++ 寫的庫存服務互相呼叫,且未來可能換到不同作業系統上跑。中介軟體最直接幫上的是哪兩件事?
為什麼說封裝與資料抽象「天生適合」分散式程式設計?
下列哪一句最能說明「互通 (interoperability)」與「可攜 (portability)」的差別?

分散式物件:熟悉又陌生

分散式物件沿用 OO 模型,但在 class、繼承、遠端參照、例外與垃圾回收上都和本地物件不同。

STEP 1

深度探秘

同樣叫物件,分散式版本多了什麼

分散式物件 = 物件 + 距離的代價

分散式物件讓你「像呼叫本地物件一樣」呼叫遠端物件,主要靠遠端方法呼叫 (RMI)。但因為物件跑在別台機器上,許多概念被升級了:

一般物件 分散式物件 多了什麼
物件參照 遠端物件參照 全域唯一、可當參數傳遞
介面 遠端介面 用 IDL 指定可被遠端呼叫的方法
動作 分散式動作 一次呼叫可能引發跨機器的呼叫鏈
例外 分散式例外 多了訊息遺失、行程失敗等狀況
垃圾回收 分散式垃圾回收 要跨機器判斷物件是否還被參照

此外,分散式物件世界裡 class 概念被淡化(異質環境難有共同 class 解讀),而且偏好介面繼承而非實作繼承。

💡
關鍵

分散式物件沿用物件模型,但遠端參照、分散式例外、分散式垃圾回收等都是為了應付『距離』而生的新成員。

STEP 2

生活妙喻

本地同事 vs. 遠距外包

找同事 vs. 找海外外包

呼叫本地物件像是轉頭問坐你旁邊的同事一件事——他一定在、一定聽得到、回答幾乎瞬間到。

呼叫分散式物件像是找一個海外外包團隊:

  • 你得有對方的聯絡方式(遠端物件參照),而且這聯絡方式要能轉交給別人。
  • 你只看得到對方公布的服務清單(遠端介面),看不到他們內部怎麼做。
  • 你的一個請求可能讓對方再去找他們的下游廠商(分散式動作的呼叫鏈)。
  • 訊息可能寄丟、對方公司可能臨時倒閉(分散式例外)。
  • 還得有人定期確認「這外包還有沒有人在用」,沒人用才能解約(分散式垃圾回收)。
flowchart TD
  A[客戶端] -->|遠端方法呼叫| B[遠端物件]
  B -->|呼叫鏈| C[下游遠端物件]
  A -.->|可能發生| D[訊息遺失或行程失敗 分散式例外]
💡
關鍵

分散式物件像找海外外包:要聯絡方式、只看服務清單、可能牽連下游、還可能出包。

STEP 3

實用超能力

中介軟體替你扛的額外苦差事

因為有距離,中介軟體要多做這些事

正因為分散式物件比本地物件複雜,中介軟體必須額外提供:

  • 物件間通訊 (inter-object communication):通常用 RMI,也常補上分散式事件等間接通訊。
  • 生命週期管理 (lifecycle management):物件的建立、遷移與刪除。
  • 啟動與停用 (activation/deactivation):物件數量龐大時不可能全部一直開著,要用到才喚醒,閒置就休眠。
  • 持久化 (persistence):物件有狀態,必須跨越啟動/停用循環甚至系統故障保存下來。
  • 額外服務:命名、安全、交易等。

為什麼要啟動/停用? 想像一個有上百萬個物件的伺服器,如果全部常駐記憶體會爆炸;所以平常讓它們「睡覺」,有請求進來才「叫醒」(activation),就像旅館不會把每間房的燈都開著等客人。

💡
關鍵

距離帶來複雜度,於是中介軟體得扛起通訊、生命週期、啟動停用、持久化與各種服務。

🔆
生活妙喻:遠端物件參照 (remote object reference) ≈ 海外外包的聯絡方式

它是全域唯一的『聯絡卡』,可以交給別人去聯絡同一個遠端物件,就像把外包窗口的名片轉交給同事。

🔆
生活妙喻:啟動與停用 (activation/deactivation) ≈ 旅館房間平常不開燈,有客人才點亮

物件數量太多不可能全常駐,平常讓它休眠省資源,收到請求才喚醒、配給執行緒,這就是啟動;反之則是停用。

本節字彙

遠端物件參照 (remote object reference)
用來指向某個分散式物件的全域唯一識別,可以當參數傳遞。
🧠 remote=遠端,reference=參照,就是『遠端物件的名片』。
介面繼承 (interface inheritance)
新介面繼承舊介面的方法簽章並可加入新方法的關係,分散式物件偏好它而非實作繼承。
🧠 只繼承『介面長相』,不繼承內部做法。
持久化 (persistence)
把有狀態物件的狀態保存下來,使其能跨越啟動/停用循環甚至系統故障。
🧠 persist=堅持存在,連關機都『堅持』把狀態留著。
一個伺服器要管理上百萬個分散式物件,但同一時間真正被呼叫的只有少數。中介軟體用哪個機制避免浪費資源?
下列哪一項是『分散式物件』相對於『一般物件』新增的概念,且專門用來應付跨機器的失敗?
為什麼分散式物件中介軟體偏好『介面繼承』而非『實作繼承』?
02

CORBA 的語言中立魔法:IDL

OMG 用 ORB 這個比喻來幫客戶端呼叫遠端物件;CORBA 物件實作 IDL 介面,客戶端不一定是物件。

ORB 與 CORBA 物件模型

OMG 用 ORB 這個比喻來幫客戶端呼叫遠端物件;CORBA 物件實作 IDL 介面,客戶端不一定是物件。

STEP 1

深度探秘

OMG、ORB 與語言中立的野心

CORBA 想解決什麼

OMG (Object Management Group) 在 1989 年成立,目標是讓不同語言、不同硬體、不同作業系統寫的分散式物件都能互相溝通。為此他們設計了一套與實作語言無關的介面語言

他們提出一個核心比喻:物件請求仲介者 (Object Request Broker, ORB)。ORB 的工作是幫客戶端在遠端物件上呼叫方法,這包含三步:

  1. 定位物件
  2. 必要時啟動物件
  3. 把客戶端的請求轉達給物件,物件執行後回覆

CORBA = Common Object Request Broker Architecture,整個架構就是繞著 ORB 這個仲介者打造的。本書聚焦 CORBA 2 規格。

💡
關鍵

OMG 用語言中立的介面語言與 ORB 仲介者,讓任何語言寫的物件都能互相呼叫方法。

STEP 2

生活妙喻

ORB 像萬能客服總機

客服總機的比喻

想像你打電話給一家大公司的總機(ORB),說:「我要找會計部處理這張發票。」你不需要知道:

  • 會計部在幾樓(定位物件
  • 承辦人現在在不在座位上、要不要先去叫他來(啟動物件
  • 你的需求怎麼被轉接過去(轉達請求

你只管講出需求,總機幫你搞定一切,承辦人處理完再回覆你。

flowchart TD
  A[客戶端] -->|我要呼叫某方法| B[ORB 物件請求仲介者]
  B --> C[定位物件]
  B --> D[必要時啟動物件]
  B --> E[轉達請求給遠端物件]
  E -->|執行並回覆| A

更厲害的是,這台總機聽得懂各國語言——不管承辦人講 C++、Java 還是 Python,總機都能橋接。

💡
關鍵

ORB 像萬能客服總機,幫你定位、喚醒並轉接到正確的承辦人,還跨語言。

STEP 3

實用超能力

CORBA 物件模型的幾個關鍵差異

CORBA 物件模型:和你想的物件不太一樣

CORBA 物件模型和一般 RMI 相似,但有幾個重要差別:

  • 客戶端不一定是物件:客戶端可以是任何送出請求訊息、接收回覆的程式。
  • CORBA 物件指的就是遠端物件:它實作一個 IDL 介面、有遠端物件參照、能回應 IDL 介面中方法的呼叫。
  • 可以用非物件導向語言實作:例如沒有 class 概念的語言也能寫 CORBA 物件。

為什麼 CORBA 沒有 class? 因為不同實作語言對 class 的理解天差地遠,有些語言甚至沒有 class。所以:

結論:CORBA IDL 不能定義 class
  → 因此 class 的實例不能當參數傳遞
  → 但任意複雜的資料結構(如 struct)可以當參數傳遞

實用差別:和單一語言的 Java RMI 比,寫 CORBA 多了三件事要學——CORBA 的物件模型、IDL、以及 IDL 到實作語言的映射。

💡
關鍵

CORBA 物件實作 IDL 介面並有遠端參照,但因為跨語言而捨棄 class,改用 struct 等資料結構傳值。

🔆
生活妙喻:物件請求仲介者 (ORB) ≈ 大公司的萬能客服總機

你只講需求,總機幫你定位部門、必要時把承辦人叫來、再轉接過去,還聽得懂各國語言——就像 ORB 跨語言定位、啟動、轉達請求。

🔆
生活妙喻:CORBA 沒有 class ≈ 國際通用的填空表格 vs. 某國專屬的精裝合約

不同國家(語言)對精裝合約(class)格式各有規定,難以通用;於是改用大家都看得懂的填空表格(struct)來傳遞資料。

本節字彙

ORB (Object Request Broker)
CORBA 中負責定位、必要時啟動並轉達客戶端請求到遠端物件的仲介軟體。
🧠 Broker=仲介,ORB 就是『物件請求的仲介』。
CORBA 物件 (CORBA object)
實作某個 IDL 介面、擁有遠端物件參照、並能回應該介面方法呼叫的遠端物件。
🧠 有介面 + 有參照 + 能被呼叫,三者俱全才算 CORBA 物件。
OMG (Object Management Group)
制定 CORBA(也管 UML 標準化)的組織,目標是推廣可互通的分散式物件系統。
🧠 管理物件的『集團』,CORBA 與 UML 都出自它手。
客戶端想呼叫一個遠端 CORBA 物件,但不知道它在哪台機器、也不知道它現在有沒有被喚醒。ORB 的角色最接近下列哪個描述?
為什麼 CORBA IDL 不能定義 class,也因此不能把 class 的實例當參數傳遞?
下列何者『不是』成為 CORBA 物件的必要條件?

用 IDL 描述介面

IDL 提供 module、interface、型別、屬性與方法簽章;參數用 in/out/inout 標註,並支援例外與介面繼承。

STEP 1

深度探秘

IDL 是一份語言中立的合約

IDL:只說『有哪些方法』,不說『怎麼做』

IDL (Interface Definition Language) 用來指定一個介面的名字與一組客戶端可以呼叫的方法。它的語法是 ANSI C++ 的子集,再加上支援分散式的關鍵字(如 interfaceinoutinoutreadonlyraises)。

IDL 提供的工具有:

  • module:把介面與型別定義分組成邏輯單位,形成命名範圍避免名稱衝突。
  • interface:描述 CORBA 物件提供哪些操作與屬性。
  • 型別:15 種基本型別(如 long、boolean)與建構型別(struct、sequence、array、union、enum 等)。
  • attribute:類似 public 欄位,編譯器會自動產生取值/設值方法(readonly 只產生取值)。

一個方法簽章的通式:

[oneway] <return_type> <method_name>(parameter1, ..., parameterL)
  [raises (except1, ..., exceptN)] [context (...)];
💡
關鍵

IDL 是語言中立的『介面合約』,描述方法、型別與屬性,但完全不談實作。

STEP 2

生活妙喻

in/out/inout 像寄包裹的方向標籤

參數方向:誰寄給誰

IDL 方法的每個參數都要標明方向,這就像在包裹上貼方向標籤:

標籤 意思 比喻
in 值從客戶端傳到伺服器 你寄東西『去』給對方
out 值從伺服器傳回客戶端 對方寄東西『回』給你
inout 兩個方向都可能傳 來回都寄(較少用)

例如:

void getPerson(in string name, out Person p);

你把 name『寄去』,伺服器把找到的 Person『寄回』。

參數傳遞語意也很關鍵:

  • 型別若是某個 IDL 介面的名字 → 傳的是遠端物件參照
  • 基本型別與建構型別 → 以值複製傳遞,到對方那邊產生新的副本。
flowchart LR
  A[客戶端] -->|in 參數| B[伺服器]
  B -->|out 參數與回傳| A
💡
關鍵

in/out/inout 標明參數流向;介面型別傳參照,基本與建構型別以值複製傳遞。

STEP 3

實用超能力

例外、繼承與一段真實 IDL

把它組起來看

一段真實的 IDL(取自白板範例):

struct GraphicalObject {
  string type;
  Rectangle enclosing;
  boolean isFilled;
};

interface Shape {
  long getVersion();
  GraphicalObject getAllState();
};

typedef sequence <Shape, 100> All;

interface ShapeList {
  exception FullException { };
  Shape newShape(in GraphicalObject g) raises (FullException);
  All allShapes();
  long getVersion();
};

重點觀察:

  • 例外newShaperaises (FullException) 宣告它可能丟出使用者自訂例外;CORBA 也會產生系統例外(伺服器太忙、通訊問題等)。客戶端兩種都該處理。
  • 介面繼承:若 interface B: A,B 繼承 A 的方法簽章並可加新項;IDL 允許多重繼承interface Z : B, C),但若 B、C 有同名項則需用 B::Q 這種範圍名稱消歧。
  • 預設呼叫語意是 at-most-once;加 oneway 則變成 maybe 語意(不阻塞、不回傳結果)。
💡
關鍵

IDL 用 raises 宣告例外、用冒號表達介面繼承(可多重),預設 at-most-once,oneway 則不阻塞。

🔆
生活妙喻:in/out/inout 參數 ≈ 包裹上的寄送方向標籤

in 是你寄去給對方、out 是對方寄回給你、inout 是來回都寄;標籤讓中介軟體知道資料該往哪個方向搬。

🔆
生活妙喻:以值傳遞 vs. 以參照傳遞 ≈ 影印一份給對方 vs. 給對方一張置物櫃鑰匙

基本與建構型別像影印副本,對方改了不影響你;介面型別像給鑰匙(遠端參照),雙方指向同一個遠端物件。

本節字彙

IDL (Interface Definition Language)
CORBA 用來定義介面、型別與方法簽章的語言中立語言,語法是 ANSI C++ 的子集加上分散式關鍵字。
🧠 Interface Definition Language=『介面定義語言』,只定義介面不寫實作。
oneway
IDL 關鍵字,使方法呼叫變成不阻塞的 maybe 語意,只能用於不回傳結果的方法。
🧠 one way=單行道,只送出去不等回來。
raises
IDL 方法簽章中宣告該方法可能丟出哪些使用者自訂例外的關鍵字。
🧠 raise=舉起/引發,引發一個例外。
在 IDL 方法 `void getPerson(in string name, out Person p);` 中,`name` 與 `p` 的資料流向分別是什麼?
某 IDL 方法回傳型別是一個 `interface Shape`,另一個參數是 `struct GraphicalObject`。這兩者的傳遞方式分別為何?
開發者想讓某個通知方法『送出後不等待回覆、也不回傳結果』,應在 IDL 中使用什麼?
03

CORBA 的架構與遠端參照

CORBA 架構在 RMI 基礎上多了物件配接器、實作儲存庫與介面儲存庫,並支援靜態與動態呼叫。

ORB core、物件配接器與儲存庫

CORBA 架構在 RMI 基礎上多了物件配接器、實作儲存庫與介面儲存庫,並支援靜態與動態呼叫。

STEP 1

深度探秘

CORBA 架構比基本 RMI 多了三個零件

三個新成員

CORBA 架構建立在 RMI 之上,但多了三個關鍵元件:物件配接器 (object adapter)實作儲存庫 (implementation repository)介面儲存庫 (interface repository)

各零件職責:

  • ORB core:包含通訊模組的全部功能,另外提供啟停 ORB、在遠端參照與字串間轉換、為動態呼叫提供引數清單等操作。
  • 物件配接器:橋接『有 IDL 介面的 CORBA 物件』與『實作它的 servant 類別』。它建立遠端物件參照、把每個 RMI 經由 skeleton 派送給對應的 servant、並負責 servant 的啟動與停用。
  • skeleton / proxy(stub):由 IDL 編譯器產生,skeleton 在伺服器語言、proxy 在客戶端語言,負責封送與解封參數、例外與結果。

CORBA 標準的物件配接器叫 POA (Portable Object Adapter),之所以『可攜』是因為它讓應用與 servant 能跑在不同開發商的 ORB 上。

💡
關鍵

CORBA 在 RMI 基礎上加了物件配接器、實作儲存庫、介面儲存庫;POA 負責把 CORBA 物件接到 servant。

STEP 2

生活妙喻

把伺服器想成一棟智慧辦公大樓

辦公大樓的各個角色

把 CORBA 伺服器想成一棟大樓:

  • ORB core = 大樓的通訊基礎建設(電話線、網路)。
  • 物件配接器 (POA) = 樓層櫃台,知道每個房號(CORBA 物件名)對應到哪位實際員工(servant),並負責把訪客帶到正確的人、員工不在就把他叫來上班(啟動/停用)。
  • 實作儲存庫 = 人資檔案室,記錄『哪個部門的程式檔放在哪、要用時去哪台機器哪個埠把伺服器叫醒』,按需啟動已註冊的伺服器。
  • 介面儲存庫 = 服務型錄查詢台,告訴你某種介面有哪些方法、每個方法要哪些參數型別——這給了 CORBA 反射 (reflection) 的能力。
flowchart TD
  A[客戶端] -->|請求| B[ORB core]
  B --> C[物件配接器 POA]
  C -->|派送| D[Servant 真正執行的物件]
  E[實作儲存庫] -->|按需啟動伺服器| C
  F[介面儲存庫] -->|提供介面資訊 反射| A
💡
關鍵

POA 是樓層櫃台、實作儲存庫是人資檔案室、介面儲存庫是型錄查詢台,三者協作把請求送到正確的 servant。

STEP 3

實用超能力

靜態 vs. 動態呼叫,與 POA 的彈性策略

編譯期就知道 vs. 執行期才知道

CORBA 同時支援兩種呼叫:

  • 靜態呼叫:遠端介面在編譯期就已知,可用客戶端 stub 與伺服器 skeleton。大多數人偏好它,因為程式模型較自然。
  • 動態呼叫 (DII):介面在編譯期未知時使用。例如一個物件瀏覽器要顯示系統裡所有 CORBA 物件,不可能事先包含所有 proxy。此時客戶端可向介面儲存庫查出方法資訊,再臨時組出呼叫送給伺服器。對應地,伺服器側有動態 skeleton 能接受未知介面的呼叫。

POA 的彈性:可設定多種策略,例如

  • 物件參照是持久 (persistent) 還是暫態 (transient)
  • 每次呼叫是否給獨立執行緒;
  • 是否每個 CORBA 物件各有專屬 servant(預設是一個 servant 服務該 POA 的所有物件)。

legacy code(舊有非分散式程式碼)也能變成 CORBA 物件:替它定義一個 IDL 介面、提供合適的物件配接器與 skeleton 即可。

💡
關鍵

介面編譯期已知用靜態呼叫,未知則用動態呼叫;POA 還能設定持久/暫態、執行緒與 servant 對應等策略。

🔆
生活妙喻:物件配接器 (POA) ≈ 樓層櫃台

它握有房號(物件名)對員工(servant)的對照表,把訪客帶到正確的人,員工不在還會把他叫來上班(啟動),訪客離開後讓他休息(停用)。

🔆
生活妙喻:介面儲存庫 (interface repository) ≈ 服務型錄查詢台

你拿到一個沒見過的物件參照,可以到查詢台問『這種介面有哪些方法、要什麼參數』,這就是 CORBA 的反射能力。

本節字彙

物件配接器 (object adapter / POA)
橋接 CORBA 物件與實作它的 servant 的元件,負責建立遠端參照、派送呼叫、啟動與停用 servant。
🧠 adapter=轉接頭,把 IDL 介面『轉接』到實際的 servant。
實作儲存庫 (implementation repository)
負責按需啟動已註冊伺服器、並記錄物件配接器名稱到實作檔路徑與伺服器位址的儲存庫。
🧠 管『實作放在哪、怎麼叫醒』的檔案室。
動態呼叫介面 (DII)
讓客戶端在編譯期不知道介面時,仍能向介面儲存庫查資訊並臨時組出呼叫的機制。
🧠 Dynamic=動態,臨場才決定怎麼呼叫。
一個物件瀏覽器需要顯示系統中所有 CORBA 物件的資訊,但這些物件的介面在它編譯時還不存在,未來也會新增。它最適合採用什麼方式?
物件配接器(POA)在 CORBA 架構中扮演的核心角色是什麼?
介面儲存庫(interface repository)為 CORBA 帶來什麼特別能力?

遠端參照 IOR 與命名服務

IOR 包含型別 ID、傳輸協定位址與物件鍵;暫態與持久 IOR 定位 servant 的方式不同,命名服務則把名字對應到參照。

STEP 1

深度探秘

IOR 是 CORBA 物件的完整門牌

IOR:可互通的物件參照

CORBA 規定了一種遠端物件參照格式,叫可互通物件參照 (Interoperable Object Reference, IOR)。它有三大欄位:

欄位 內容 作用
IDL 介面型別 ID 介面的型別識別 若有介面儲存庫,可用來取回 IDL 定義
協定與位址細節 例如 IIOP 下的主機網域名稱與埠號 找到伺服器在哪
物件鍵 (object key) 物件配接器名稱 + 物件名稱 ORB 用來辨識是哪個 CORBA 物件

IIOP (Internet Inter-ORB Protocol) 使用 TCP,位址就是主機網域名稱加埠號。第二個欄位可重複,以指定多個位址,達成複製與容錯。

💡
關鍵

IOR 是 CORBA 物件的完整門牌,含型別 ID、協定位址與物件鍵三欄。

STEP 2

生活妙喻

暫態 vs. 持久 IOR:臨時攤位 vs. 連鎖總部

兩種門牌,兩種找人方式

IOR 分兩種,定位 servant 的方式不同:

  • 暫態 IOR (transient):只在『裝著該物件的行程』活著時有效,門牌上寫的是伺服器本身的位址

    • 找法:伺服器 ORB core 收到請求 → 用物件配接器名稱找到配接器 → 用物件名稱找到 servant。
    • 比喻:路邊臨時攤位,攤位收了門牌就失效。
  • 持久 IOR (persistent):能跨越物件的多次啟動,門牌上寫的是實作儲存庫的位址

    • 找法:實作儲存庫收到請求 → 取出物件配接器名稱 → 必要時在登記的主機位址啟動 CORBA 物件 → 把實際位址回給客戶端 ORB,之後客戶端直接對該位址送請求。
    • 比喻:連鎖店總部,你先找總部,總部告訴你現在哪家分店在營業。
flowchart TD
  A[客戶端 ORB] -->|暫態 IOR| B[伺服器 ORB core 直接定位 servant]
  A -->|持久 IOR| C[實作儲存庫]
  C -->|必要時啟動並回傳位址| A
💡
關鍵

暫態 IOR 直接指向伺服器、隨行程消失;持久 IOR 指向實作儲存庫、可跨啟動定位。

STEP 3

實用超能力

命名服務:給物件一個好記的名字

別讓人類記 IOR

IOR 對機器很完美,但對人類來說又長又難記。命名服務 (Naming service) 就是來解決這件事:它把人類可讀的名字對應到遠端物件參照,是任何 ORB 幾乎都要加上的基礎服務。

典型用法(Java):伺服器把物件以名字 rebind 到命名服務,客戶端再用同樣的名字 resolve 取回參照。

// 伺服器端:把 ShapeList 物件以名字註冊
NameComponent nc = new NameComponent("ShapeList", "");
NameComponent path[] = { nc };
ncRef.rebind(path, SLRef);

// 客戶端:用名字取回參照
ShapeList shapeListRef =
    ShapeListHelper.narrow(ncRef.resolve(path));

注意 narrowresolve 回傳的是泛用的 Object 型別,要『窄化』成你真正需要的型別(ShapeList)。

對比命名與交易服務:命名服務用名字找物件;交易服務 (Trading service) 則用屬性找物件,像目錄服務——你說『我要一個會做 X、價格低於 Y 的服務』。

💡
關鍵

命名服務把好記的名字對應到遠端參照,用 rebind 註冊、resolve 取回,再用 narrow 窄化型別。

🔆
生活妙喻:暫態 IOR vs. 持久 IOR ≈ 路邊臨時攤位 vs. 連鎖店總部

暫態 IOR 像臨時攤位,攤位收了門牌就失效;持久 IOR 像先找連鎖總部,總部再告訴你目前哪家分店在營業(必要時把物件啟動)。

🔆
生活妙喻:命名服務 (Naming service) ≈ 電話簿

你不必背別人的長串電話號碼(IOR),只要查名字就能找到對應號碼(遠端參照)。

本節字彙

IOR (Interoperable Object Reference)
CORBA 的標準遠端物件參照格式,含 IDL 介面型別 ID、協定位址細節與物件鍵三欄。
🧠 Interoperable=可互通,是跨 ORB 都認得的『物件門牌』。
命名服務 (Naming service)
把人類可讀的名字對應到遠端物件參照的 CORBA 服務,用 rebind 註冊、resolve 取回。
🧠 Naming=命名,幫物件取個好記的名字。
narrow (窄化)
把命名服務 resolve 回傳的泛用 Object 型別轉換成所需的具體型別的操作。
🧠 narrow=變窄,從泛用型別收窄成你要的型別。
一個 CORBA 物件需要在多次啟動之間都能被定位,而非只在某個行程存活期間有效。它應該使用哪種 IOR,且該 IOR 內存的是誰的位址?
IOR 的三大欄位是下列哪一組?
為什麼實務上會用命名服務,而不直接把 IOR 交給人類使用?
04

從物件演進到元件

隱性相依、需懂大量中介軟體細節、關注點纏繞、部署全靠手工,是催生元件式做法的四個需求。

分散式物件的四大痛點

隱性相依、需懂大量中介軟體細節、關注點纏繞、部署全靠手工,是催生元件式做法的四個需求。

STEP 1

深度探秘

分散式物件很好用,但有四個結構性問題

為什麼還要演進到元件

分散式物件(如 CORBA)很成功,但實務上暴露出四個痛點,正是它們催生了元件式做法:

  1. 隱性相依 (implicit dependencies):物件介面只說明它『提供』什麼,沒說明它『依賴』什麼。物件內部可能偷偷呼叫別的物件或命名、安全等服務,但這些從外部介面看不出來。
  2. 與中介軟體的互動太複雜:就算標榜透明,程式設計師仍被迫處理大量低階細節——命名、POA、ORB core 等呼叫,把真正的應用邏輯淹沒。
  3. 缺乏分散式關注點的分離:安全、交易、協調、複製這些非功能性需求,得由開發者親手在物件中插入呼叫,造成關注點纏繞。
  4. 沒有部署支援:物件得手動部署到每台機器、手動啟動、手動建立綁定,大規模部署既累又易錯,且不可攜。
💡
關鍵

分散式物件的四大痛點是:隱性相依、與中介軟體糾纏、無法分離分散式關注點、缺乏部署支援。

STEP 2

生活妙喻

找水電工 vs. 找一個只報價不說工具的師傅

隱性相依:看不見的依賴最可怕

想像你請一位師傅來裝冷氣(他公布的『介面』是:我會裝冷氣)。但他沒告訴你:

  • 他得先借用你家的電鑽(依賴別的工具)
  • 還得打電話叫一個搬運工來幫忙(依賴別的服務)

這些隱性相依讓你很難評估:換另一位師傅行不行?少了搬運工會不會出事?這正是物件介面『只說提供、不說依賴』的問題。

再看關注點纏繞:好比食譜裡,把『怎麼煮這道菜』和『瓦斯怎麼開、抽油煙機怎麼接電、廚房防火怎麼做』全寫在一起——真正的料理步驟反而被淹沒。

flowchart TD
  A[物件對外介面 只說提供什麼] --> B[實際上偷偷依賴]
  B --> C[其他物件]
  B --> D[命名服務]
  B --> E[安全與交易服務]
  A -. 看不見這些依賴 .-> B
💡
關鍵

隱性相依像『只報價、不說會用到哪些工具與幫手』的師傅,讓人難以替換與安全組裝。

STEP 3

實用超能力

每個痛點都對應一個明確需求

痛點 → 需求:元件要補的洞

書中把每個痛點轉成一個明確需求,這正是元件式中介軟體要實現的目標:

痛點 對應需求
隱性相依 不只要描述物件提供的介面,也要描述它對其他物件的依賴
與中介軟體糾纏 乾淨分離『中介軟體框架程式』與『應用程式』,讓開發者只專注後者
關注點未分離 把安全、交易等分散式服務的複雜度盡量對開發者隱藏
無部署支援 中介軟體應內建部署支援,讓分散式軟體像安裝單機軟體一樣容易

回看真實例子:CORBA 的 whiteboard 範例裡,伺服器其實會對客戶端 callback、客戶端與伺服器都會呼叫命名服務——但這些都沒寫在對外介面上(隱性相依);而真正和白板有關的程式碼很少,卻和一堆分散式系統呼叫交織在一起(關注點纏繞)。這就是為什麼需要演進。

💡
關鍵

四個痛點各自對應一個需求:顯式描述依賴、分離中介軟體與應用、隱藏分散式服務複雜度、內建部署支援。

🔆
生活妙喻:隱性相依 (implicit dependencies) ≈ 只報價、不說會借用哪些工具與幫手的師傅

你只看到他公布『我會裝冷氣』,卻不知道他暗中依賴你的電鑽和一個搬運工,導致你很難評估替換或安全組裝。

🔆
生活妙喻:關注點未分離 ≈ 把料理步驟和瓦斯接線、防火工程寫在同一份食譜

安全、交易等分散式關注點和應用邏輯纏在一起,真正的『料理步驟』被技術細節淹沒,程式變得又長又難懂。

本節字彙

隱性相依 (implicit dependencies)
物件介面只描述提供什麼,卻未表明它依賴哪些其他物件或服務,使組裝、替換與第三方開發變困難。
🧠 implicit=隱含的,看不見的依賴最難處理。
非功能性需求 (non-functional concerns)
如安全、交易、協調、複製等與『功能本身』無關但攸關系統品質的需求。
🧠 不是『做什麼功能』,而是『做得安不安全、可不可靠』。
關注點分離 (separation of concerns)
把不同類別的程式邏輯(如應用邏輯與分散式服務呼叫)清楚分開,避免纏繞。
🧠 各管各的,互不打結。
某物件對外介面寫著『提供下單功能』,但實作裡其實還會呼叫命名服務、對客戶端做 callback。第三方開發者因此難以安全替換它。這對應到分散式物件的哪個痛點?
在 CORBA 白板範例中,真正與白板有關的程式碼很少,卻和大量 POA、ORB、命名服務呼叫交織在一起。這暴露了哪個痛點?
下列哪一項『不是』書中列出的分散式物件四大痛點之一?

元件、容器與部署

元件用提供介面與必要介面寫清楚相依;容器扛起非功能性需求;部署描述子讓部署像裝單機軟體一樣簡單。

STEP 1

深度探秘

元件:把依賴也寫進合約

元件的定義

Szyperski 的經典定義:

軟體元件是一個組合單位,具有契約式指定的介面僅有明確的上下文相依

關鍵字是『僅有』——意思是所有上下文相依都必須明確 (explicit),沒有任何隱性相依。元件像分散式物件一樣是封裝的組合單位,但它的契約同時包含:

  • 提供介面 (provided interfaces):它對外提供的服務。
  • 必要介面 (required interfaces):它正常運作所依賴、必須被連接上的其他元件。

在一個元件組態中,每個必要介面都必須綁定到另一個元件的提供介面。這就形成了一份軟體架構:元件 + 介面 + 介面間的連接。

元件擁護者強調組合優於繼承,因為繼承會在類別間製造另一種隱性相依(如脆弱基礎類別問題)。

💡
關鍵

元件同時宣告提供介面與必要介面,把所有依賴寫成明確契約,杜絕隱性相依。

STEP 2

生活妙喻

元件像有公母插頭的電器,容器像保母

提供/必要介面像插頭與插座

把元件想成一台電器:

  • 提供介面 = 它對外能輸出的服務,好比它身上的插座,別人可以插進來用。
  • 必要介面 = 它自己要運作所需的依賴,好比它的插頭,必須插到別人的插座才能通電。

組裝系統就像把一堆電器的插頭和插座一一接好——軟體開發因此從『開發』走向『組裝 (assembly)』,可以用現成元件拼出更複雜的服務。

容器 (container) 則像一個盡責的保母/管家:它把元件包在裡面,不讓外界直接碰元件,而是攔截 (interception) 所有進來的呼叫,先替元件處理好安全、交易、生命週期等雜事,再放行給元件。

flowchart TD
  A[進來的呼叫] --> B[容器 攔截]
  B --> C[呼叫安全與交易服務]
  B --> D[管理 ORB 與生命週期]
  B --> E[元件 只負責應用邏輯]
💡
關鍵

提供/必要介面像插座與插頭,靠組裝拼系統;容器像保母,靠攔截替元件扛下分散式雜事。

STEP 3

實用超能力

容器、應用伺服器與部署描述子

容器補齊了另外三個需求

上一節元件定義解決了『隱性相依』,但簡化開發、隱藏服務複雜度、支援部署這三項,是靠容器補上的。容器支援常見的三層模式:

  • 前端(常為 web)客戶端
  • 容器,內含實作應用/商業邏輯的元件
  • 系統服務,管理持久儲存中的資料

支援容器模式與關注點分離的中介軟體就叫應用伺服器 (application server),例如 WebSphere、EJB、Spring、JBoss、GlassFish。它的好處是把分散式複雜度藏起來,例如 POA 相關呼叫由容器代勞、交易與安全靠攔截自動處理。

部署支援部署描述子 (deployment descriptor),通常用 XML 寫,描述:

<!-- 概念示意:部署描述子說明如何部署元件組態 -->
<deployment>
  <component name="OrderService" required="InventoryService"/>
  <transaction policy="container-managed"/>
  <security level="required"/>
</deployment>

元件被部署進容器,容器解讀部署描述子來設定底層中介軟體與分散式服務的政策;工具則據此在實體架構上正確部署。

💡
關鍵

容器用攔截扛下非功能性需求形成應用伺服器;部署描述子(常為 XML)讓部署像裝單機軟體一樣自動化。

🔆
生活妙喻:提供介面與必要介面 ≈ 電器的插座與插頭

提供介面像插座讓別人插進來用,必要介面像插頭必須接到別人的插座才能通電;組裝系統就是把插頭插座一一接好。

🔆
生活妙喻:容器 (container) ≈ 盡責的保母/管家

外界的呼叫不直接碰元件,而是先被容器攔截,由它替元件打理好安全、交易、生命週期等雜事,元件只管做自己的應用邏輯。

本節字彙

提供介面 / 必要介面 (provided / required interfaces)
元件對外提供的服務介面,以及元件正常運作所依賴、必須被連接的其他元件介面。
🧠 提供=我給你的(插座),必要=我需要的(插頭)。
容器 (container)
在伺服器端託管元件、透過攔截替元件處理安全、交易、生命週期等非功能性需求的環境。
🧠 把元件『裝在裡面』並代為打理雜事的容器。
部署描述子 (deployment descriptor)
通常以 XML 撰寫、描述元件組態如何在分散式環境中部署與配置的檔案。
🧠 descriptor=描述書,描述『怎麼部署』。
依 Szyperski 的定義,元件與一般分散式物件最關鍵的差別是什麼?
把元件比喻成電器時,『必要介面』對應到什麼,又代表什麼意義?
容器主要透過什麼機制,在不更動元件應用邏輯的前提下,替它加上安全、交易等非功能性處理?
05

元件案例:EJB 與 Fractal

EJB 用 POJO 加註解開發 bean,容器負責交易、安全與生命週期,並支援相依注入與攔截。

Enterprise JavaBeans:受管的三層式元件

EJB 用 POJO 加註解開發 bean,容器負責交易、安全與生命週期,並支援相依注入與攔截。

STEP 1

深度探秘

EJB 是伺服器端、受管的元件架構

EJB 是什麼

Enterprise JavaBeans (EJB) 是 Java EE 的核心,是一種伺服器端、受管 (managed) 的元件架構。元件在 EJB 中叫 bean,負責承載應用(商業)邏輯,並把這層邏輯和後端資料庫的持久儲存分開——直接支援三層式架構

『受管』指的是用上一節的容器模式:容器透過攔截,自動替 bean 注入交易、安全、生命週期等服務的呼叫(container-managed);開發者也可選擇自己掌控(bean-managed)。

EJB 3.0 支援兩種主要 bean:

  • Session bean(會談 bean):實作某項任務,例如在 eShop 下單。可以是
    • stateful:維持與單一客戶端的對話狀態(如購物進度);
    • stateless:不維持狀態,能同時和多個客戶端對話。
  • Message-driven bean(訊息驅動 bean):支援間接通訊,透過 JMS 的訊息佇列或主題以事件驅動方式互動。
💡
關鍵

EJB 是伺服器端受管元件架構,bean 承載商業邏輯,容器代管交易、安全與生命週期,直接支援三層式架構。

STEP 2

生活妙喻

POJO 加註解,像給普通員工別上識別證

POJO + 註解:簡單到不可思議

EJB 3.0 大幅簡化了開發:一個 bean 其實就是一個 POJO (Plain Old Java Object)——純粹用 Java 寫的應用邏輯,裡面沒有任何與『它是 bean』有關的程式碼。然後用註解 (annotations) 來告訴框架該怎麼對待它。

比喻:POJO 像一位普通員工,本身就會做事;註解就像別在他身上的識別證與職務標籤——『@Stateful:我是有狀態會談』『@Remote:我這個窗口對外開放』。識別證不改變他會做的事,只是讓大樓系統(容器)知道該給他什麼待遇。

@Stateful public class eShop implements Orders { ... }
@Stateless public class CalculatorBean implements Calculator { ... }
@MessageDriven public class SharePrice implements MessageListener { ... }

@Remote public interface Orders { ... }   // 對外遠端介面
@Local public interface Calculator { ... } // 僅本地、較高效

business interface 等於上一節的『提供介面』;@Remote 需透過 RMI/JMS 等通訊中介軟體,@Local 則是更直接、更高效的綁定。

💡
關鍵

bean 是純 Java 的 POJO,加上註解就像別上識別證,讓容器知道該給它什麼樣的管理待遇。

STEP 3

實用超能力

交易、相依注入與攔截器,全靠註解

用註解駕馭容器

交易管理:先宣告由 bean 還是容器管理:

  • @TransactionManagement(BEAN):開發者自己用 UserTransaction.begin()commit() 框出交易範圍。
  • @TransactionManagement(CONTAINER)預設):容器決定何時開始/結束,搭配方法上的劃界政策。

常見交易屬性(劃界政策):

屬性 政策
REQUIRED 有現存交易就加入,否則開新交易
REQUIRES_NEW 一律開新交易
MANDATORY 必須由現存客戶端交易呼叫,否則丟例外
NEVER 絕不能在交易中被呼叫,否則丟例外

相依注入 (dependency injection):用 @Resource 等註解標出依賴,容器在執行期(常用反射)把對的物件填進去——這正是元件『必要介面』在 EJB 的實現。

攔截 (interception):用 @AroundInvoke 在不改商業邏輯下插入橫切行為(如記錄、稽核);用 @PostConstruct@PreDestroy(stateful 還有 @PostActivate@PrePassivate)回應生命週期事件。

@Stateful public class eShop implements Orders {
  @Resource javax.transaction.UserTransaction ut; // 相依注入

  @TransactionAttribute(REQUIRED)
  public void MakeOrder(...) { ... }

  @AroundInvoke
  public Object log(InvocationContext ctx) throws Exception {
    System.out.println("called: " + ctx.getMethod().getName());
    return ctx.proceed();
  }
}
💡
關鍵

EJB 用註解統一駕馭交易劃界、相依注入與攔截,讓開發者專注商業邏輯、把分散式管理交給容器。

🔆
生活妙喻:POJO + 註解 ≈ 普通員工別上識別證與職務標籤

POJO 本身就會做事(應用邏輯),註解像識別證,不改變他做的事,只讓大樓系統(容器)知道該給他什麼待遇與管理。

🔆
生活妙喻:相依注入 (dependency injection) ≈ 你列出所需食材清單,廚房幫你備齊送來

元件用註解列出依賴,容器這個第三方負責在執行期把對的物件『送進來』填好,你不必自己去找與建立。

本節字彙

bean
EJB 中的元件,承載應用(商業)邏輯,部署到容器中由容器代管非功能性需求。
🧠 EJB 的元件就叫 bean,一顆顆組成系統。
POJO (Plain Old Java Object)
純粹用 Java 寫、不含框架特定程式碼的普通物件;EJB 3.0 的 bean 就是 POJO 加註解。
🧠 Plain Old=樸素老派,普通到不能再普通的 Java 物件。
相依注入 (dependency injection)
由第三方(容器)負責解析並在執行期把元件所需的依賴填入的模式,常以註解與反射實現。
🧠 依賴由外部『注入』進來,你不用自己找。
在 eShop 中,購物車需要記住單一客戶整個結帳過程的進度;另一個計算服務則只需快速處理大量無關客戶的請求。這兩者分別適合哪種 session bean?
EJB 3.0 中『一個 bean 就是 POJO 加上註解』這句話的意涵是什麼?
某方法標註 `@TransactionAttribute(REQUIRED)`。當呼叫端『已經』有一個進行中的交易時,會發生什麼?

Fractal:輕量可重組的元件模型

Fractal 顯式表示軟體架構,提供 server 與 client 介面,刻意極簡、語言中立,常用來建構其他中介軟體。

STEP 1

深度探秘

刻意極簡的元件模型

Fractal 走的是另一條路

EJB 是重量級、處方式 (prescriptive) 的應用伺服器,強大但龐大,只適合三層式、高階伺服器的場景。Fractal 則是輕量級元件模型,刻意極簡:沒有完整容器模式、不內建部署,也沒有應用伺服器那種豐富程式模型。

Fractal 的特點:

  • 顯式表示軟體架構:避免隱性相依問題(呼應上一章的元件精神)。
  • 語言中立:定義的是程式模型,有 Java(Julia、AOKell)、C(Cecilia、Think)、.NET、Smalltalk、Python 等多種實作。
  • 常被用來建構其他中介軟體,例如可設定的 OS 核心 Think、間接通訊平台 DREAM、Grid 平台 Proactive 等。

元件提供兩種介面:

  • server 介面:接收進來的呼叫(等於『提供介面』)。
  • client 介面:發出向外的呼叫(等於『必要介面』)。
💡
關鍵

Fractal 是輕量、語言中立、顯式描述架構的元件模型,刻意極簡,常用來打造其他中介軟體。

STEP 2

生活妙喻

膜與控制器,像細胞與它的細胞膜

細胞的比喻

Fractal 元件在實作上由兩部分組成,恰好像一個細胞

  • 內容 (content) = 細胞質:構成這個元件的子元件與它們之間的綁定(階層式組合,子元件本身還能再是複合元件)。
  • 膜 (membrane) = 細胞膜:定義這個元件的控制能力,由一組控制器 (controllers) 組成。膜決定外界如何與內容互動,介面可分『膜內可見』與『對外可見』。

換掉膜上的控制器,就改變了元件的能力——這正是 Fractal『可重組』的關鍵。控制器的用途包括:

  • 生命週期管理:如 LifeCycleController 的 startFc/stopFc/getFcState,可在執行期暫停、替換、再恢復。
  • 反射/自省:透過 Component 與 ContentController 介面動態探查元件有哪些介面、複合結構長怎樣。
  • 攔截:和 EJB 一樣可透明地記錄呼叫或實施存取控制。
flowchart TD
  A[膜 控制器集合] --> B[生命週期管理]
  A --> C[反射與自省]
  A --> D[攔截]
  A --> E[內容 子元件與綁定]
💡
關鍵

Fractal 元件像細胞:膜由控制器組成、掌管生命週期反射與攔截,內容是階層式的子元件與綁定。

STEP 3

實用超能力

綁定、ADL 與執行期重組

用綁定與 ADL 組裝,還能熱抽換

綁定 (bindings) 讓元件能組合,有兩種:

  • primitive binding:同一位址空間內,一個 client 介面直接對映一個 server 介面(型別相容時),可用直接物件參照高效實作。
  • composite binding:任意複雜的架構,實作跨機器多介面的通訊。例如要在 Fractal 裡實作一條 CORBA 連線,這個綁定本身會由 proxy、ORB core、物件配接器、skeleton、servant 等元件組成。複合綁定本身也是元件,所以系統完全可設定、也可在執行期重組。

Fractal ADL(架構描述語言,基於 XML)用來描述組合:

<definition name="cs.ClientServer">
  <interface name="r" role="server" signature="java.lang.Runnable" />
  <component name="caller" definition="hw.CallerImpl" />
  <component name="callee" definition="hw.CalleeImpl" />
  <binding client="this.r" server="caller.r" />
  <binding client="caller.s" server="callee.s" />
</definition>

膜 vs. 容器:膜和容器都是元件的部署處、都支援隱式分散式管理(容器靠呼叫服務、膜靠控制器)。但膜更有彈性:反射可從黑箱到完整自省、非功能性支援可從『只做封裝』到『像應用伺服器般的交易與安全』,且全程可設定、可重組。正因如此,Fractal 被稱為開放元件模型 (open component model)

熱抽換的實用情境:把 client-server 配置裡的舊伺服器換成支援多執行緒的新版——可先 suspend、替換 callee、再 resume,避免不一致。

💡
關鍵

Fractal 用 primitive/composite 綁定與 XML 的 ADL 組裝系統,膜比容器更有彈性,可在執行期安全熱抽換元件。

🔆
生活妙喻:膜與內容 (membrane and content) ≈ 細胞膜與細胞質

膜(控制器集合)像細胞膜,掌管元件對外的控制能力;內容像細胞質,是構成元件的子元件與綁定。換掉膜上的控制器就改變了能力。

🔆
生活妙喻:執行期重組(熱抽換元件) ≈ 演唱會中途換掉故障音響卻不中斷表演

先暫停受影響的部分、換上更強的元件、再恢復,就像舞台技術人員在表演進行中安全地替換設備,避免不一致。

本節字彙

膜 (membrane)
Fractal 元件中由一組控制器構成的控制部分,定義元件的生命週期、反射、攔截等控制能力。
🧠 membrane=膜,像細胞膜決定『外界怎麼跟內容互動』。
控制器 (controller)
位於膜中、提供特定控制能力(如生命週期管理、自省、攔截)的元件;換控制器即換能力。
🧠 controller=控制器,掌控元件的某項能力。
綁定 (binding)
Fractal 中連接介面以實現組合的機制,分為同位址空間直接對映的 primitive 與跨機器複雜架構的 composite。
🧠 binding=綁定,把 client 介面綁到 server 介面。
一個團隊需要在資源受限、且常需在執行期調整通訊結構的環境中建構中介軟體,不想要 EJB 那種龐大、處方式的負擔。下列哪個模型較符合需求?
在 Fractal 中,元件的 server 介面與 client 介面分別對應到上一章元件術語的什麼?
用細胞比喻 Fractal 元件時,『膜 (membrane)』掌管的是什麼?