跳轉到內容

計算機程式設計/基於元件的軟體開發

來自華夏公益教科書

軟體工程學士學位

所有書架 > 科學 > 計算機科學 > 計算機程式設計 > 基於元件的軟體開發

面向元件的程式設計

[編輯 | 編輯原始碼]

軟體元件目前是軟體工程界最流行的術語之一。本章概述了元件技術、其重用概念和特性。然後,我們將簡要概述軟體架構及其與基於元件的開發的關係。最後,我們將以 JavaBeans 為例,考察元件模型。

軟體危機

[編輯 | 編輯原始碼]

1968 年,在加米施-帕滕基興的北約會議上,首次提到了“軟體危機”。人們承認軟體開發很困難,甚至困難到必須被視為一項獨立的工程學科。同時,人們也抱有希望,認為從困境中走出來的途徑可能是形成一個新的軟體元件產業和元件市場。

軟體開發的現狀與 19 世紀初的許多行業類似:產品是手工製作的,昂貴且容易出錯。成熟行業的特徵是,它製造的產品是由許多小型標準化且可互換的部件組裝而成的。

例如,電子工程領域,像二極體、電阻器和電晶體這樣的小型電子元件並非為單一應用而設計,而是為許多不同的應用而設計。它們可以在電路板上組合成更大的積體電路 (IC)。一個單一零件可以簡單地用其他零件替換,只要它提供相同的功能。ISO、ANSI 或 DIN 等標準保證了元件的相容性和可互換性。

元件的特徵

[編輯 | 編輯原始碼]

軟體開發試圖模仿這些重用機制。其理念是透過以“即插即用”的方式組裝一套獨立開發的“現成”(COTS)元件來開發軟體系統。

“軟體元件”的概念已經相當古老,但近年來它已經發生了很大變化。在早期的程式設計時代,軟體元件主要被視為原始碼模組,比如 FORTRAN 庫,而現在對元件的要求更多了。關於軟體元件到底是什麼,沒有普遍認可的定義。問題在於,觀點很大程度上取決於作者的背景,而且近年來關於元件的討論非常多,以至於元件的概念變得有些模糊不清。

然而,人們通常將一些通用屬性與軟體元件聯絡起來。一個很好的起點是 ECOOP 96 大會上提出的定義:

'"軟體元件是具有合同指定介面和顯式上下文依賴關係的組合單元。軟體元件可以獨立部署,並且可以由第三方進行組合。"'Clemens Szyperski,《元件軟體》,ACM 出版社/艾迪生-韋斯利出版社,英國,(1998 年)。

接下來,我們將更詳細地描述定義中出現的不熟悉的術語。

元件特性

[編輯 | 編輯原始碼]

資訊隱藏

[編輯 | 編輯原始碼]

可能最重要的特徵是,元件完全隱藏了它們的實現。Parnas 的資訊隱藏原則早在很早的時候就強調了這一點。

“每個模組都隱藏了一個重要的設計決策及其實現,隱藏在明確定義的介面後面,當設計決策或實現發生變化時,該介面不會發生變化”。

元件就像黑盒子:程式設計師知道盒子外是什麼樣子,以及元件能提供什麼,但他不知道元件內部是如何工作的。乍一看,這種完全封裝似乎是一種限制,但我們會看到它實際上是一種幫助。

應用程式構建者從中獲益,因為他可以用另一個元件替換該元件,只要它支援相同的介面和功能。此外,他不需要了解元件的內部工作原理,只需要瞭解元件的介面。

另一方面,元件提供者可以改變元件的實現,只要介面仍然滿足。介面是 CBSD 中一個非常重要的術語。它被定義為“表示一個功能的命名方法集合”。介面充當元件提供者和元件使用者之間的一種契約。它不僅應該說明元件的服務,還應該說明它對其環境的依賴關係。

沒有原始碼會帶來一些需要解決的困難。首先,仍然必須能夠將元件調整到使用者的特定需求。在不知道元件實現的情況下進行調整被稱為定製。此外,元件必須提供一個機制來獲取關於其規範的資訊。這種自描述性是透過內省來實現的。

上下文無關性

[編輯 | 編輯原始碼]

元件可以輕鬆地轉移到不同的應用程式環境中。因此,元件需要是自包含的軟體元素,獨立於任何其他元件。這種獨立性是如此嚴格,以至於甚至不允許實現繼承,因為實現繼承會使元件依賴於它的超類,而改變超類會導致元件崩潰。介面繼承只是一種對特徵規範的簡單概括,是允許的。

隱式呼叫。

[編輯 | 編輯原始碼]

為了使元件可交換,元件最好不要直接相互定址,而是透過間接機制。一箇中央登錄檔儲存所有關於元件和介面的資訊。每次客戶端想要呼叫一個方法時,它都會查詢登錄檔以獲取所需的介面,該介面反過來會返回一個對實現該介面的元件的引用。

元件模型

[編輯 | 編輯原始碼]

對元件的下一個要求是它們是可互操作的,這意味著它們必須具有與用另一種程式語言編寫或位於不同主機的元件進行通訊的能力。此外,它們本身也必須能夠轉移到其他作業系統和硬體平臺上。這些要求是透過虛擬機器、交叉編譯器和中介軟體來保證的,比如來自 Sybase 的Avaki EII、來自 OMG 的 CORBA 和來自微軟的 DCOM。

元件不是孤立地使用,而是根據軟體架構使用,軟體架構決定了元件可以具有的介面以及元件如何組合。元件模型提供了一個元件之間互動的通用框架。元件模型是必須遵循的程式設計指南,以便可以使用元件。在框架之外,元件是不可用的。兩個重要的元件模型是來自 Sun Microsystems 的 JavaBeans 和來自微軟的 ActiveX,後者基於元件物件模型 (COM)。CBSD 的關注和成功主要歸功於這兩個元件模型。但是,現有的元件模型都沒有實現人們對元件的所有期望的功能。

CBSD 的影響

[編輯 | 編輯原始碼]

如果有一天 CBSD 真正大規模建立起來,它將從根本上改變軟體的開發方式。透過元件化開發,程式設計元件的過程與將元件組合成應用程式的過程分離。希望元件能像樂高積木一樣輕鬆地拼裝在一起,而無需編寫原始碼。因此,即使是技術技能較少的領域專家也能組裝應用程式。

此外,CBD 預計將對軟體開發的質量產生重大影響。

  • 由於簡單性,軟體開發速度加快。無需從頭開始開發一切,因為可以購買第三方元件。開發時間縮短,從而降低了成本。
  • 元件增強了軟體的可靠性,因為它們經過多年的改進、測試和除錯。除此之外,組合者可以選擇和組合來自不同供應商的最佳元件。
  • 軟體系統的可擴充套件性和可演化性得到了提高,因為元件可以靈活地被滿足要求的另一個元件替換。

幾年前,這種前景在軟體開發界引起了狂熱,因為人們期待元件能解決很多問題。現在,一些幻滅正在蔓延。CBSD 變得非常困難,因為軟體由許多緊密耦合的相互作用實體組成,這些實體不能以直接的方式連線在一起。

與面向物件程式設計的區別

[編輯 | 編輯原始碼]

通常,元件和物件會被混淆或混在一起。元件化開發確實借鑑了面向物件方法的許多概念。如今,元件化開發建立在 OOP 基礎上,但比面向物件方法提供了更抽象的軟體系統檢視。

主要區別在於元件是完全封裝的,正如我們剛剛看到的。元件嚴格禁止訪問其內部,而在 OOP 中,需要了解物件的內部工作機制,例如從類繼承時。這種 OOP 中的重用機制也稱為白盒重用,因為原始碼對洞察和修改是開放的。

此外,構建塊的粒度也不同:元件存在於不同的尺寸,從庫中的單個物件到整個應用程式。但在大多數情況下,元件是更大的實體,包含多個物件。

組合模式和軟體架構

[編輯 | 編輯原始碼]

OOP 的一個難點是互動協議的表示。在面向物件程式設計中,全域性控制流分佈在多個物件上。因此,對互動協議的修改會導致多個物件的更改,這阻礙了系統的直接演化。另一個問題是,物件只能在具有相似互動模式的系統中重用。

元件技術允許將軟體系統的架構表示為可重用的實體。架構描述語言 (ADL) 使用抽象角色之間的協作來描述軟體系統。角色是實際存在元件的一種佔位符。在組合時,這些角色透過單獨的聯結器用元件填充。

好處是

  • 元件包含較少的上下文依賴關係,因此更容易轉移到其他軟體系統。
  • 互動協議可以重用。
  • 軟體架構促進為系統建立精心設計的結構,而不是駭客將元件拼湊在一起。良好的結構提高了軟體系統的可維護性,以便以後更容易進行更改。

JavaBeans 元件模型

[編輯 | 編輯原始碼]

JavaBeans 是主流的 Java 元件模型,由 Sun Microsystems 於 1996 年推出。它考慮了構成元件的最重要特性。JavaBeans 定義如下

"JavaBean 是一個可重用的軟體元件,可以在構建工具中進行視覺化操作。"

Sun 與元件模型一起釋出了一個簡單的視覺化組合工具,即 BeanBox。它更適合於用 Bean 進行實驗,而不是提供專業的 IDE。對於實際應用,最好使用 Visual Age 或 JBuilder 等支援 JavaBeans 視覺化組合的 Java IDE 之一。

正如我們所見,JavaBeans 與標準 Java 類沒有太大區別。這使得 Bean 元件模型非常易於使用。但 JavaBeans 可能擁有一些大多數普通 Java 類不具備的功能

  • 永續性
  • 屬性
  • 內省
  • 事件通訊
  • 自定義

永續性

[編輯 | 編輯原始碼]

一個物件成為 Bean 的要求是定義一個公共無引數建構函式,以便構建工具可以以簡單的方式例項化 Bean(在 Point Bean 中,無引數建構函式是隱式給出的)。其次,需要實現java.io.Serializablejava.io.Externalizable介面之一。這些介面沒有規定任何方法的實現,而是表示 Bean 可以儲存在持久儲存中,例如在檔案或資料庫中。這樣,應用程式關閉或跨網路傳輸後,可以恢復 Bean。在持久儲存中儲存元件狀態的能力稱為永續性。Java 提供了標準的序列化機制,這使得序列化物件變得非常容易。或者,元件可以透過實現Externalizable介面以自定義方式儲存(例如,以 xml 格式)。

Bean 的屬性是所有可透過公共方法訪問和修改的欄位。這些 getter 和 setter 方法應該按照一定的命名方案標記為相應方法。

<PropertyName>(PropertyType).

另一方面,訪問器方法由以下模式程式設計

public PropertyType get<PropertyName>()

這種命名約定背後的意圖是,它幫助構建工具找出 Bean 的工作原理以及它的功能。正如我們所見,元件必須提供有關其服務的資訊,這稱為內省。JavaBeans 提供了兩種內省機制:反射和BeanInfo類。BeanInfos 提供了有關 Bean 元件的複雜資訊,但必須顯式實現。

JavaBeans 透過事件相互互動。事件是元件可以傳送給其他元件的通知,表明發生了有趣的事情。滑鼠單擊按鈕或關閉視窗就是一個事件的示例。Bean 可以是事件的源和目標。要接收事件的通知,Bean 必須在另一個 Bean 上註冊為偵聽器

Java 事件模型實現了觀察者設計模式,其效果是降低了元件間的耦合。方法呼叫需要緊密耦合,因為呼叫者和接收者需要在編譯時相互瞭解,而事件的所有通訊都僅透過介面進行。

一種特殊的事件是PropertyChangeEvents。它們用於限制某些屬性只能取特定值,例如,對於月份,整數值在 1 到 31 之間。每次修改此類繫結屬性時,都會向所有註冊的PropertyChangeListeners傳送通知。

自定義

[編輯 | 編輯原始碼]

自定義透過 *屬性編輯器* 完成。屬性編輯器是用於在設計時自定義特定屬性型別的工具。屬性編輯器從所謂的 *屬性表* 啟用,屬性表顯示了 Bean 的所有屬性。如果選擇了要自定義的屬性,屬性表會找出屬性的型別,並顯示相應的屬性編輯器以及屬性的當前值。

最終說明

[編輯 | 編輯原始碼]

JavaBeans 元件模型的一個主要優勢在於它設計得非常簡單。開發 JavaBeans 很簡單,因為許多行為(比如平臺獨立性或打包機制)在 Java 程式語言中預設得到支援。但是,可以選擇為 Bean 新增額外的物件,例如 *BeanInfos* 或自定義 *PropertyEditors*,以便更靈活地使用元件模型。第二個功能是 Sun 根據 JavaBeans 元件模型設計了整個 Swing GUI 庫。因此,Swing 元件可以在視覺化構建工具中輕鬆組合。

但是,JavaBeans 並沒有實現元件模型的所有功能。一個缺點是 JavaBeans 僅限於 Java 程式語言,而元件的重要目標是實現語言的獨立性。

華夏公益教科書