構件組裝-理論與技術

第二章 相關理論與技術

本章主要介紹了本文研究的相關理論與技術,包括構件組裝相關理論、SOA相關技術標準、OSGi相關技術標準、模型驅動相關技術標準、代碼生成相關概念與技術以及領域工程相關理論,這些理論與技術構成了本文研究的基礎。

2.1構件組裝相關理論

1968年的NATO軟件工程會議上,Mcllroy在提交會議的論文《大量生產的軟件構件》中,提出了“軟件組裝生產線”的思想5。簡單的講,構件組裝就是採用“搭積木”的方式來生產軟件。分析傳統工業及計算機硬件產業成功的模式可以發現,這些工業的發展模式均是符合標準的零部件(構件)生產以及基於標準構件的產品生產(組裝)。構件組裝是軟件工業化生產的必由之路。

構件是系統構成成分的標準形態,組裝是構件演化的原則與方式,及自底向上的系統構建方法。構件組裝成功運用的前提是標準化的構件與構件組裝機制。面向構件組裝的開發,通過長期積累形成完備的構件庫,以構件組裝的方式快速構建軟件系統,以構件增減的方式快速響應業務需求的變化,從而使軟件開發具備了“敏捷性”,使軟件系統具備了“彈性”。

2.1.1構件組裝源自軟件複用

軟件複用(Software Reuse)通常指軟件本身可重用,即代碼可重用。但隨着技術的發展,軟件複用已遠不止這些,軟件開發的整個生命週期都有可複用的價值,包括項目組織、需求分析、系統設計、項目文檔、實現代碼、測試方法以及測試用例等等,都是可以被重複利用或借鑑的有效資源。

利用軟件複用,可以充分利用已有成果來構建新系統,消除分析、設計、編碼、測試等階段的許多重複勞動,從而提高開發效率;同時,通過複用高質量的已有成果,可以避免重新開發可能引入的錯誤,從而提高產品質量。因此,軟件複用同樣可顯著的提高軟件開發效率與產品質量。

軟件複用與構件組裝存在殊途同歸之妙。

但分析軟件複用的過程後發現,軟件複用中存在兩個基本的開發活動:面向複用的開發與基於複用的開發,從構件組裝的角度看,前者其實是可複用構件的生產,後者是利用可複用構件組裝新系統。可以看出,構件組裝實質上是軟件複用標準化的進一步探索,構件組裝源自軟件複用,軟件複用是構件組裝的基礎。

2.1.2構件組裝的研究內容

構件組裝是支持軟件複用的核心技術,其研究內容主要包括:

(1)構件獲取:有目的的構件生產以及從遺留系統中挖掘並提取構件;

(2)構件模型:研究構件的本質特徵以及構件之間的關係;

(3)構件描述語言:基於構件模型,解決構件描述、理解以及組裝等問題;

(4)構件分類與檢索:研究構件分類策略、組織模式及檢索策略,建立構件庫系統,支持構件的有效管理,保存構件資產,減低構件查找與理解的成本;

(5)軟件架構:研究軟件系統自身的整體結構的刻畫以及構件之間的互聯。

(6)構件組裝:以軟件架構爲藍圖,在構件模型以及描述語言的基礎上研究構件組裝機制,包括源代碼級的組裝和基於構件對象互操作性的運行級組裝;

(7)標準化:構件模型與構件組裝機制的標準化以及構件庫系統的標準化。

2.1.3中間件技術促進構件組裝

中間件技術(MiddleWare)是軟件複用發展的產物,是軟件系統開發的基礎類軟件,屬於可複用軟件,它通常位於操作系統與數據庫之上、應用軟件之下,管理計算資源以及網絡通信等,爲上層應用提供開發與運行的環境,以便實現靈活、高效的系統開發以及複雜應用的集成。中間件通常具備如下特點:

(1)支持標準協議;

(2)支持標準接口;

(3)支持分佈式計算;

(4)支持多種硬件與操作系統。

近年來,中間件技術的迅速發展使得構件組裝的系統開發成爲可能。中間件技術作爲介於系統軟件與應用軟件之間的特殊層次,抽象了典型的應用模式,使開發人員可以將精力更多的放在業務邏輯上,並基於標準的形式進行開發。而如Corba、Com/DCom及Ejb等工業標準的出現,進一步使中間件成爲構件組裝的運行框架,加速了構件組裝的發展。

但是,基於中間件技術的構件組裝關注的是標準運行級構件基於中間件基礎設施自底向上的構造系統,這就使得構件組裝的模型與實現極大地依賴於具體的中間件實現技術,而缺少針對構件組裝本質特徵的高層描述與系統化的指導開發的方法,以及從高層描述與到技術實現上的映射。

2.1.4 SA指導構件組裝

軟件架構SA爲面向構件組裝的系統開發提供了一種自頂向下的系統化指導方法。SA將系統的整體結構作爲研究對象,在高層顯式的描述系統構成元素及其之間的交互關係6,並指導驗證系統設計。從構件組裝的角度看,SA通常存在對象連接式、接口連接式、插頭插座式三種類型。

對象連接式體系結構,構件接口只定義了其對外提供的服務,而沒有定義構件對外要求的服務,這種非對稱性使得構件在集成時,構件對外要求的服務被隱藏在代碼的實現細節中,即構件之間的連接關係無法直接在接口處定義。

接口連接式體系結構,構件接口不但定義了其對外提供的功能,而且定義了其要求的外部功能,從而顯式地表達了構件對環境的依賴,提高了構件接口規約的表達能力。但是當接口定義的功能數量很大時,便帶來了規模上的問題。

插頭插座式體系結構,考慮到構件之間的通信往往涉及到構件接口中功能的成組連接,並且在這組功能之間通常存在着一定的語義約束關係,例如使用順序連接與數據流協議等,通過把這樣的彼此間關係緊密的功能組織成組,並封裝爲服務,從而使得接口中直接包含的內容減少,降低了接口中功能的規模。

從構件組裝的角度看,SA描述的是軟件系統的基本組織,包括構件、構件之間、構件與環境之間的關係及相關設計與演化原則。SA的貢獻在於將構件之間的交互顯式的定義爲連接件,並將連接件與構件等同的視爲系統構成的一階實體6,並使得接口不匹配的構件之間可以通過連接件進行連接,發展了接口匹配的構件連接。但目前SA的研究集中在通過軟件體系結構描述語言ADL(Architecture DescriptionLanguage)對SA的描述和高層性質的驗證上,對體系結構的求精與技術實現的支持能力明顯不足6

2.1.5構件組裝提升面向對象技術

構件組裝並非是對現有的分析、設計方法的顛覆,而是在此基礎之上的繼承與發展。面向對象技術基於傳統的結構化技術提升了對事物的認識方法,使軟件開發儘可能接近人類認識世界、解決問題的方法與過程,即使描述問題的問題空間與實現解法的解空間在結構上儘可能一致,從而直觀、自然的在解空間內求解出問題空間內問題的穩定且易複用解。

相對於面向對象技術,構件組裝更多的將重點放在軟件生產的考慮上,即構件在軟件生產中作爲零件被納入軟件體系中而被複用,強調構件作爲零件所需具備的特徵及爲實現零件組裝所具備的構件之間的協調關係,認識事物的角度從個體本身上升到個體在羣體中的作用。

但面向對象技術並不能完整實現構件組裝,對象連接式體系結構中已分析。

構件通過接口封裝內部實現,通過屬性標識構件狀態,通過接口定義同外界交互的全部內容,接口是構件同外界交互的唯一途徑,除此之外,外界不應對構件作任何的其他的與接口無關的假設。構件接口分爲:爲實現被組裝而提供服務的接口與爲實現組裝而引用服務的接口。面向對象技術只定義了對外提供服務的接口,所需引用服務的接口隱藏在內部實現中,使得組裝無法直接在接口處顯式定義,靈活性大大降低。

所以,單純依靠現有的面向對象技術無法完整的實現構件組裝,需要藉助於其它輔助技術手段提高抽象程度,使得構件能夠在接口處顯式定義組裝,比較好的選擇便是藉助於模型驅動技術。

2.1.6模型驅動的構件組裝

模型驅動的構件組裝,通過構件組裝模型在高層顯式定義構件提供服務的接口與引用服務的接口,描述基於接口或連接件的構件組裝機制,並通過代碼生成器結合代碼模板產生構件組裝的連接件代碼甚至構件代碼,實現構件組裝的高層模型到程序代碼的完整生成。而ADL本質上即是一種描述構件組裝的模型。

ADL描述構件接口的語法和語義、系統中的構件和連接件以及它們之間的交互關係、構件的非功能類性質以及構件之間的協議,爲構件組裝提供更爲有力的支持6。但爲了支持構件組裝,ADL 還應該更多地關注體系結構描述的求精和實現,提供支持轉換或組裝自動化的能力7

2.1.7樣例代碼支持靜態組裝

SA是系統的高層規劃,提供系統劃分與設計的方法,定義系統靜態結構與動態交互等關係,在高層爲系統搭建提供理論指導。目前常用的有MVC(Model、View、Controller)三層架構。SF是系統架構指導下對系統的共性部分進行抽象提煉形成的實現基礎,在此之上開發完整的業務系統。目前常用的有SSH(Struts,Spring,Hibernate)框架。SA與SF是軟件發展成熟的表現,它以複用爲目標,使軟件開發不必從零開始。

樣例代碼是面向業務、以系統框架爲基礎建立的完整的、可運行的程序代碼,它說明了以SF爲基礎如何開發業務系統的問題。要實現生成100%的程序代碼必須參照完整的樣例代碼製作代碼模板,即對樣例代碼整體模板化。以SSH框架爲例,需要將包括Jsp、Js、Config、ApplicationContext、Hibernate hbm、Po、Vo、Do、Dao、Service、Action等在內的所有程序資源製作成代碼模板。這就要求樣例代碼的完整性及對不同業務類型的覆蓋度。

建立完整的、覆蓋不同業務類型的樣例代碼,並將樣例代碼整體模板化,是實現從構件組裝的高層模型到程序代碼的完整生成的快速、靈活且有效的方法。

2.1.8構件組裝理論的本質

構件組裝的本質是在構件之間建立關聯並協調行爲。構件通過接口或連接件進行連接,其實質是通過接口或連接件建立關聯並協調行爲。但是當構件接口數量很大時,構件連接的規模便成了問題。所以,插頭插座式體系結構將存在語義約束的多個接口組織成組並封裝爲服務,只有對偶服務之間才能連接,在一定程度上降低了接口規模,但其不能將無語義約束的接口組織成高級接口。而接口綁定則把多個功能耦合的內部接口組織爲外部接口,封裝爲功能更強更抽象的複合接口,從而提高接口粒度、減少接口的數量、降低連接規模,並提高了構件組裝的抽象級別8。但複合接口的交互協議也因內部接口之間的聯繫而變得複雜,所以複合接口又建立了根據多個內部接口及其交互協議推導複合接口交互協議的構件組裝機制,共有6種,分別是:並行、選擇、複製、順序、中斷、連接8。這6種組裝機制涵蓋了接口綁定的構件組裝發生時構件之間的行爲協調關係。

總結構件組裝機制的發展看出:構件組裝的本質是在構件之間通過接口或連接件建立關聯並協調行爲,當發生關聯的構件中有原子構件時,與原子構件通過接口或連接件建立連接,但當發生關聯的構件中有複合構件時,與複合構件連接其實是與複合構件中的內部構件通過接口或連接件建立連接,而內部構件之間可能存在既無接口又無連接件連接的情況,這種情況便是接口綁定,即從複合構件的角度看是多個內部接口綁定到外部接口並根據內部接口的交互協議推導外部接口的交互協議,而從複合構件組裝的角度看,本質上仍然是外部構件通過接口或連接件與複合構件的內部構件連接並推導基於接口或連接件連接的交互協議。

所以,基於接口或連接件連接的交互協議是描述構件連接的普適性交互協議。而接口連接發生在對偶接口之間,其實是連接件連接的特殊情況。連接件是SA研究的貢獻,不同的SA風格中構件之間的交互協議不同,形成了不同類型的連接件,所以出現了通用連接件模型9,但通用連接件模型建立的仍然是基於接口綁定的組裝機制,而本文建立的是具備普適性的基於連接件連接的構件之間交互的控制結構,即普適性的構件組裝機制。

2.1.9構件組裝的數學基礎

分形理論是研究非線性科學的前沿理論之一,是研究事物複雜性、從有限認識無限的特殊規律的學科。哲學研究上,人們很早就認識到整體由部分組成,可以通過認識部分來映像整體,系統中每個元素都反映和含有整個系統的性質和信息,即元素映像系統,這是分形理論的哲學基礎之一。

從分析事物的視角方面來看,分形理論和系統論分別體現了從兩個極端出發的思路,它們之間的互補恰恰完整地構成了辨證的思維方法。系統論由整體出發來確立各部分的系統性質,它是沿着宏觀到微觀的方向考察整體與部分之間的相關性。而分形理論則相反,它是從部分出發確立了部分依賴於整體的性質,沿着微觀到宏觀的方向展開的。系統論強調了部分依賴於整體的性質,而分形理論則強調整體對部分的依賴性質,二者構成“互補”10。 所以,分形理論爲人們從部分認識整體,從有限認知無限提供了可能的依據。

分形理論反映了自然界中廣泛存在的一類“事物”的基本屬性:部分與部分,部分與整體在幾何結構與形態、過程、信息、功能、性質、能量、物質、時間、空間等特徵上具有統計意義上的自相似性,即幾何或非線性變換下的不變性,在不同放大倍數上的性狀相似。組成部分以某種方式與整體相似的形體則稱爲分形。分形並非是部分或整體放大或縮小一定倍數後簡單的與整體或部分完全重合,通常是在無標度空間內表徵自相似性的定量性質,如分形維數,不會因放大或縮小而發生變化,這被稱爲標度不變性或伸縮對稱性,即分形體無特徵長度11。而自相似性是不同尺度上的對稱,是跨層次的共性觀,同樣形態在不同尺度、不同層次上的相同,或相似結構的重複構建與變換,其結構套着結構,特徵或結構隱含嵌套,具有多層次性和遞歸性。分形元是構成分形整體、相對獨立的、放大與縮小均不改變及共同相似的基本部分,即相似單元。相似單位,或是變換中不變性的共同的、最基本的、簡單的結構、性質的單位或單元,是整體與部分共性的統一體。

以構件爲基本單元的軟件體系結構認爲:軟件系統的基本組成包括構件、構件之間、構件與環境(指中間件)之間的關係,以及相關的設計與演化規則。構件是軟件系統的基本組成單元,小構件通過組裝形成大構件,簡單構件通過組裝形成複雜構件,最終由構件組裝形成整個軟件系統。由分形理論知,組裝起到相當於放大的作用,大構件與小構件間,複雜構件與簡單構件間,均具備組裝形態上的相似性,即原始構件及組裝產生的構件均可以作爲構件而被組裝。構件是軟件系統的基本構成成分,組裝是構件演變的方式,是軟件系統構建的方式。組裝產生的構件又會被作爲新的構件進行新的組裝,從而構件組裝中存在着分形元,分形元即是具備組裝特性的構件,構件在不同粒度、層次上均具有同樣形態,即組裝特性。因構件無粒度,即軟件系統可通過無限制層次的構件組裝產生,所以,構件組裝的分形維數爲無窮大。由此,通過基於分形理論的構件組裝技術,分形構件組裝,使得傳統產業生產模式中的符合標準的零部件(構件)生產以及基於標準構件的產品生產(組裝),在軟件生產中形成。

分形理論可作爲構件組裝的數學基礎。

2.2 SOA相關理論與技術標準

1996年Gartner提出面向服務架構SOA(Service-OrientedArchitecture),目的是讓企業業務更加“敏捷”,軟件系統變得更有“彈性”,使企業能快速響應需求的變化。可以看出,SOA與構件組裝有着共同的目標。從最初的實現原則、架構模型、參考模型,直到目前的編程模型,SOA在不斷髮展並逐漸成熟,2007年2月,OSOA組織在將SCA(Service ComponentArchitecture)標準提交給OASIS,2009年初,SCA由行業標準變成了真正的國際標準。

2.2.1 SOA實現原則與架構模型

SOA是指導企業實現業務敏捷性以及建設彈性軟件系統的架構模型,引用Bloomberg 的SOA實現原則:

(1)業務驅動服務,服務驅動技術;

(2)業務敏捷是基本的業務需求;

(3)一個成功的SOA總在變化之中。

SOA的核心圍繞着業務敏捷性展開。實現業務敏捷性首先要求業務本身就具備敏捷性,業務本身就能夠對變更快速而有效的響應,這其實是企業管理建設上考慮的事情,最本質的作法是企業從自身來發現問題所在並改正。業務具備敏捷性後,接下來考慮的纔是通過彈性軟件系統來更好的表達業務敏捷性,也就是如何用軟件系統更好的表達現實當中的業務,即業務建模。

SOA在秉承這一目標的同時,更多了一個考慮:如何應對出現的各種變化。而這些變化主要集中在兩個方面:現實世界的發展變化與軟件系統本身的發展變化。現實世界的不斷變化,要求軟件系統能夠適應這種變化,軟件系統本身也在不斷地發展變化,要求新建軟件系統能夠兼顧遺留系統,而只有建設自身就在不斷變化的軟件系統,才能應對現實世界的不斷變化,只有建設技術實現無關的軟件系統,才能實現新建軟件系統與遺留軟件系統的兼顧。這就是SOA要解決的問題。變化是軟件系統建設決不可迴避的問題。

上述表明,SOA架構模型的本質還是業務建模,側重於爲應對變化而需要敏捷性的業務建模,至於服務只是業務模型暴露出來的形式,以統一的服務形式描述業務模型。業務的變化是在模型內部的變化,業務敏捷性反映在業務建模的敏捷性上,而服務則解決敏捷業務間的互操作問題。由此可以看出服務只是業務的包裝形式,這種形式只要可以解決互操作問題,而可以不問形式到底是什麼。這就是爲什麼有人說:從Rpc、Ipc直至分佈式計算的Corba、Com/Dcom、Ejb等,幾乎都帶有SOA的影子。從SOA架構模型來理解,它們只是服務的形式,服務形式發展歷史上經歷的技術成熟階段的產物。目前階段的SOA肯定也不會是終極形式,只能說是到目前爲止最爲成熟的形式而已。

分析到這裏,可以看出SOA架構模型除包含具有業務敏捷性的業務建模之外,另一重要內容即是技術形式最爲成熟的服務。但爲實現業務敏捷性,業務建模與服務形式之間又存在着交叉,即當業務模型以統一的服務形式暴露出來後,便可以通過組裝模型組裝具有統一服務形式的業務模型,以期實現更大範圍的業務敏捷性,這也是目前SOA研究範疇中非常重要的部分,即以統一的服務形式爲基礎,通過組裝模型,實現更大範圍的業務敏捷性。SOA架構模型包含以統一的服務形式爲基礎通過組裝模型實現更大範圍的業務建模。

而2005年前後出現的針對遺留系統的整合技術,本文認爲只是一種過渡技術,是SOA服務形式探索道路上的階段性產物。整合解決的是軟件系統間的互聯互通問題,而SOA的組裝模型並不侷限於此,所以兩種技術針對遺留系統的解決方案也不盡相同:組裝必須首先以遺留系統的服務化改造爲基礎,然後以統一的服務形式進行組裝,而整合則無此必要步驟。在這裏本文不展開來討論了。

2.2.2 SOA服務的基本特徵

那麼技術形式最爲成熟的服務到底是一個什麼樣子呢?截至目前爲止,這一服務形式還在研究與制定當中,這裏不能妄下結論。但服務所具備的特徵卻是在業界有共同認識的。服務具備的特徵歸納爲如下幾點:

(1)服務自治

自治隱藏了服務封裝、服務具備明確的邊界且獨立運行的特點。服務接口是服務與外界交流溝通的唯一途徑,通過服務接口封裝服務的內部實現,通過服務接口發佈服務自己具有的功能,通過服務接口實現服務間的調用,而並不依賴環境上下文,服務接口以內的變化絕對不會影響到接口以外,接口以外的變化也不會影響到接口以內,而服務接口使用統一的表達形式,描述服務具備的功能性與非功能性的能力與特點及服務使用方式,服務接口是服務與外界的明確邊界。服務接口以內則獨立地維護與運行。可以看出,SOA服務在功能上等同於構件組裝中的構件,只是存在形式上不同而已。

(2)服務鬆耦合

鬆耦合隱藏了服務位置透明、基於傳輸協議的消息交換等特點。有人認爲鬆耦合應該從多個緯度來理解,因爲鬆耦合在這些緯度上均有表現。這些緯度包括:

A)時間,時間上的鬆耦合可以使交互雙方不必在同一時間進行通訊,即服務使用者發出請求即可,服務提供者發出回覆即可。

B)位置,位置上的鬆耦合可以使交互雙方在不作任何改變的情況下而適應雙方可能在物理地址的變化。

C)接口,接口上的鬆耦合使交互雙方可以綁定到特定接口,也可以綁定到通用接口,而所有通用接口的使用者都能與該接口的提供者進行通訊。

D)查找,查找上的鬆耦合使服務使用者可以通過明確的物理或邏輯位置來查找並使用,也可通過註冊機構或目錄服務中查找來匹配服務提供者並使用它。

E)其他緯度還包括:類型、版本、基數等等,CarlosPerez已詳細分析。

(3)服務互操作

互操作隱藏了服務環境異構、服務複用等特點,服務使用服務接口作爲邊界隔離服務內部的環境異構,通過多協議接口實現服務間通訊協議的環境異構,從而實現異構環境下服務互操作,並以此爲基礎實現服務複用。

以上只是歸納總結了服務所具備的主要特徵,當然服務肯定也存在其他特徵。從上面的分析可以看出,SOA架構模型是指導企業實現業務敏捷性的指導原則與建設彈性軟件系統進行體系結構設計的方法。可以看出,在目標上、甚至模型架構上,SOA與構件組裝都極其相似。

2.2.3 SOA爲何不是WebService

SOA在方法論上逐漸成熟成爲轉向應用的充要條件,而WebService的適時出現,促成了SOA的初次體驗。但SOA卻不是WebService,二者也已漸行漸遠。

WebService可以追溯到HP在上世紀90年代末期的分佈式計算研究項目,E-Speak,使用Http協議提供XML數據,將互聯網作爲電子服務。緊接着出現的是XML-RPC與ebXML,前者由UserLand領導,後者由OASIS與UN/CEFACT共同開發和維護,他們都在探索一種技術中立的、基於分佈式計算解決互聯互通互操作問題的方案。這些技術其實是WebService發展道路上的必然產物。

SOAP可以視爲XML-RPC的升級,改善了Verbosity與Data Typing,同樣出自UserLand,並於1999年下半年正式發佈。而IBM、MicroSoft、Ariba等廠商在早期WIDL、SDL、SCL、DISCO、NASSL、ADS等規範的基礎上最終形成了WebService描述語言WSDL和WebService通用描述、發現與集成協議UDDI。這樣WebService協議棧中主要協議都已形成。2001年4月,W3C WebService研討會,WSWS,正式召開,討論WebService發展規劃,如何構建WebService協議棧,包括Qos、安全以及事務等標準,這標誌着WebService標準化正式開始。

但隨着2000年以科技股爲代表的納斯達克股市的崩盤和互聯網泡沫的破滅,業內艱難時期來臨,企業爲生存而掙扎,直到2002年,情況纔有所好轉。在這期間,唯一能打動客戶的方案無疑就是如何節約成本,而這正是WebService所具備的優點:成本低廉的集成方案。所以這一時期被認爲是WebService的黃金時期,至2003年,WebService更是火爆異常。

但IT界獨有的快節奏卻也使WebService的問題早早暴露:協議棧並不能保證互操作,並且標準化也不能降低異構環境下系統間的差異,WebService成本低廉的集成方案更難以降低業務變化的長期成本。到後來,WebService組織分化,各自發布並維護標準、規範,標準化組織主要有兩個,分別是W3C與OASIS,前者發佈了SOAP與WSDL,後者則負責維護UDDI,業內廠商聯盟WS-I,則致力於解決環境異構下標準互操作問題。

SOA不是WebService,首先因爲SOA早於WebService出現,如上面提到的,SOA在開始的很長時間裏只是個方法,並且致力於解決業務敏捷性,所以SOA極力尋找一種技術中立的實現,至90年代末期,即WebService協議棧標準開始形成,並且基於被各大廠商認爲會成爲理想消息協議的XML,所以在那個時期,業內認爲WebService就是SOA。但SOA解決業務敏捷性的目標是沒有變過的,所以當後來WebService基於標準的集成方案並不能達成SOA業務敏捷性目標的時候,二者的分開便是不可避免的了。所以會有人說:WebService只是目前最適合實現SOA的技術。而SOA卻不是WebService。WebService基於標準的應用編程接口,缺乏SOA的鬆耦合、位置透明等特徵,更不能實現業務敏捷性,並且WebService服務難以管理。

2.2.4 SOA編程模型:SCA與SDO

2005年底,OSOA組織制定了SOA編程模型,SCA與SDO(Service Data Objects)。SOA編程模型從業務需求出發,以開放的服務構件與動態交互技術爲基礎,將鬆耦合的服務構件快速組裝成業務流程,完成業務活動,從而實現軟件系統業務敏捷性。而SCA與SDO則是相互關聯的規範,SCA關注業務邏輯,SDO側重於業務數據。

圖2-1 SCA 服務構件

SCA描述面向服務的計算環境裏服務構件與組裝模型的實現方法,強調服務構件與平臺及服務構件之間的關聯,並描述怎樣通過已有的技術、平臺甚至構件來實現服務構件,確定統一、通用的服務構件接口及其語義,建立服務構件間鬆耦合的交互環境,並定義服務構件組裝模型。開放的服務構件與服務構件組裝具有模型技術獨立、平臺獨立、語言獨立等技術特性,廠商們可以在不同平臺上使用不同技術和語言來實現。

圖2-2 SCA複合構件

服務構件組裝模型的目標是融合實現服務構件以及服務構件間訪問方法的廣泛技術。對於服務構件而言,不僅涉及不同的編程語言,而且也涉及到這些編程語言的架構及運行環境。對於訪問方法而言,組裝模型允許使用常用的通訊與訪問技術,包括WebService,消息及RPC等。組裝模型允許使用多種技術來實現,包括Java,C++,Bpel,Php,Javascript,Xquery,Sql等12

圖2-3 SCA組裝系統

服務構件組裝模型組裝起來的應用系統,既可以包括全新定製的服務構件,也可以包括存在於現有系統中的業務邏輯。這些現有的業務邏輯,作爲應用系統的一部分而進行復用。組裝模型涉及了服務構件的組裝和服務構件的創建,並且也涵蓋了現有應用系統功能的複用。

SDO則是高度抽象的業務數據模型,主要描述業務數據對象及其內部各種粒度的數據對象之間的關聯,以統一的方式訪問或操作不同類型的數據源,並進行持久化。SDO提供連接器,可以通過不同方式且環境透明地與多種數據源交互,同時還提供諸如連接池、緩存、斷開連接時數據訪問等高級特性。另外,SDO還提供中介轉換器,可以根據業務語義定義完整的業務模式,並提供對象圖表,與連接器交互,完成數據持久化工作。SDO可以充分提高數據管理的效率13

上述分析表明,SOA編程模型,SCA與SDO,從較高的抽象層次上對SOA架構模型做了技術中立的實現,並從業務驅動的角度,以簡潔、通用且技術開放的服務構件及組裝方式更貼切的表達業務需求,使開發人員脫離開底層技術實現的細節,更多的關注於業務邏輯的分析、設計,而軟件系統架構卻不失開放性、靈活性等等特徵,在業務數據處理方面則以統一的方式管理多種類型的數據源,充分提高數據管理的效率。

2.2.5 SCA實現運行級構件組裝

通過上述分析可以看出,SCA規範中的服務構件可視爲運行級代碼構件,組裝模型(SCA中稱爲Assembly)可等同視爲構件組裝模型。服務構件通過對外提供的服務(Service)與所要引用的服務(Reference),在服務構件之間建立關聯並協調行爲,形成服務構件的組裝,組裝後產生複合構件(Composite),複合構件可將其內部的某服務構件的某些Service或Reference暴露爲複合構件的Service或Reference,從而使得複合構件又可以作爲服務構件而再次進行組裝,服務構件與複合構件均通過其屬性(Property)來設置自身的狀態及其他屬性信息。

SCA較好的實現了運行級的構件組裝,而構件可以作爲服務構件較好的實現手段,首先因爲構件具備服務構件的基本特徵,可以很容易的封裝爲服務構件,其次構件組裝與SOA有着共同的目標,即提升軟件開發效率與產品質量,實現軟件複用,以及快速適應需求變化,所以,構件是服務構件較好的實現手段。

2.3OSGi相關技術標準

2.3.1 OSGi偏重運行級構件組裝

OSGi(Open Service GatewayInitiative)最初目的是爲各種嵌入式設備提供通用的軟件運行平臺,屏蔽操作系統與硬件區別的中間件平臺,提供對不同廠商提供的應用構件進行生命週期管理的能力,如應用構件可以在運行時被安裝、升級或者移除而不需要中斷設備操作,應用構件可以動態的發現和使用其他應用程序。由於OSGi技術具有模塊化、動態加載等優點,正被越來越多的領域關注,如嵌入式設備製造、汽車製造、企業應用等。目前,OSGi聯盟發佈的最新的OSGi規範版本爲4.0,並且已經爲一些通用的功能,如HTTP服務器、配置、日誌記錄、安全、用戶管理、XML等,開發了很多標準構件接口,並由不同的軟件供應商提供。

目前,OSGi逐漸演化爲面向構件的架構標準,但與SCA不同的是,OSGi更偏重於針對單一JVM中服務的動態綁定,即更多的考慮了運行時框架和服務在運行時刻的動態匹配等問題,它強調運行時的組裝,而並不注重對構件組裝模型本身的刻畫,且OSGi只適用於Java平臺。可以看出,SCA過於強調組裝模型,對服務構件的運行時組裝描述太弱,所有構件組裝實現都是在設計時綁定的。也許在SCA中可以實現運行時的動態綁定,但是作爲一個規範,這是它所欠缺的。OSGi規範對運行時構件的相關描述很完備,但是所有構件必須運行在同一JVM中,不同JVM中的組件服務互操作則明顯不足。

下面將詳細介紹OSGi相關規範。

2.3.2 OSGi相關技術規範

(1)Framework規範

Framework規範是OSGi規範的核心組成部分,它提供了通用的、安全的、可管理的Java Framework。通過Framework爲應用程序提供一個標準化的環境。

圖2-4 Framework層次圖

如圖所示,Framework包括四個層次:L0運行環境層;L1模塊層;L2生命週期管理層;L3服務註冊層;另外,還包括貫穿各層的安全機制。

1)L0運行環境層

L0運行環境層是Java環境規範。Java2配置和子規範,如J2SE、CDC、CLDC、MIDP等,都是有效的運行環境。OSGi還標準化了基於基本Profile的執行環境和可用於OSGi Bundle的最小執行環境的規範。

2)L1模塊層

L1模塊層定義了類裝載策略。OSGi框架是一個強大而又嚴格定義的類裝載模型。Java通常只定義單個類路徑,裏面包括了所有的類和資源。模塊層爲每個模塊添加私有的類並控制模塊之間的關聯。

3)L2生命週期管理層

L2生命週期管理層可負責動態安裝、啓動、停止、更新和卸載Bundle。Bundle加載類時依賴模塊層,但是添加了運行期管理模塊的API。生命週期管理層引入了應用程序通常不具有的動態性,而擴展的依賴機制則保證了環境的正確運行。

4)L3服務註冊層

L3服務註冊層通過服務註冊表,爲Bundle提供了協作模塊的動態註冊能力。Bundle可以通過傳統的類共享來協作,但是類共享與動態安裝與卸載的代碼不太協調,服務註冊表爲Bundle之間共享對象提供了一個合理的協作模型。

5)安全機制

安全機制基於Java安全模型,通過優化的語言設計來減少可能的安全漏洞,通過語言中的訪問控制限制其他開發者對代碼的可見度,OSGi提供私有類擴展,並添加了完整的動態權限管理機制。

6)Bundle

OSGi環境中,Framework管理Bundle的安裝、更新、刪除以及與服務之間的依賴關係,爲Bundle開發者提供簡明一致的編程模型,簡化開發部署的複雜性,避免可預計的錯誤。Framework可運行在不同的硬件環境上,通過接口的一致性確保軟件運行在統一的服務接口之上。Bundle共有以下六個狀態:

INSTALLED:安裝完成,本地資源成功加載;

RESOLVED:依賴關係滿足,代表Bundle已經準備好運行,或已被停止;

STARTING:Bundle正在被啓動;

STOPPING:Bundle正在被停止;

ACTIVE:Bundle 被成功啓動並且在運行;

UNINSTALLED:Bundle被卸載並且無法進入其他狀態。

(2)標準服務規範

Framework定義了很多抽象服務,而服務的具體實現由不同廠商提供。

1)Framework Service

Framework提供權限管理服務(Permission Admin Service)、包管理服務(Package Admin Service)以及系統服務加載(Start Level Service)等。

2)System Service

系統服務提供每個實際系統所需要的底層功能。如Log Service,Configuration AdminService,Device Access Service,User Admin Service,IO Connector Service,Preferences Service。

3)Protocol Service

協議服務主要包括:Http Service、UPnP Service 、Jini Service等。

4)Miscellaneous Service

WireAdmin Service:在配置文件中定義的Service之間的連接與對象交換。

XMLParser Service:XML解析服務,兼容JAXP。

OSGi規範有廣泛的適用性,它專注於單一JVM中服務的動態綁定,提供可擴展的安全機制使構件運行在受保護的環境裏,提供可擴展的排隊機制使構件組裝變得可能與安全。目前,許多廠商和組織對OSGi規範做了實現,主要有:IBM SMF、開源項目Oscar、Eclipse Equinox、Apache Felix等。

2.3.3 Eclipse Plug-in架構

Eclipse無疑是目前OSGi規範實現最好的項目,它是面向軟件開發、基於Plug-in架構、可擴展的、開源的開發平臺,它是由微內核、標準 Plug-in以及用戶自定義Plug-in構成的開發環境。Eclipse 自帶的標準Plug-in集主要有 Java 開發工具JDT(Java Development Tools)與Plug-in開發環境PDE(Plug-in DevelopmentEnvironment)。PDE主要面向希望擴展 Eclipse 功能的Plug-in開發人員。

圖2-5 Eclipse Plug-in構件

EclipsePlug-in架構如上圖所示,其核心是微內核,即Platform runtime,所有的功能都以Plug-in形式插接到微內核上。這樣的功能Plug-in包括各種圖形API、JDT、PDE環境等。Eclipse對這些Plug-in的協同工作提供了良好的支持,對於Plug-in的裝載與調用都是動態實現的。當Eclipse啓動後真正需要用到某Plug-in時,纔將其裝載入內存,當不需要使用時,清除出內存。這樣就保證了啓動和使用的性能。

Eclipse.org官方網站上,目前最常用的Plug-in項目如下:

AJDT:AspectJ開發工具;

BIRT:報表工具;

Buckminster:自動構建,組裝和部署工具;

CDT:C/C++開發工具;

DLTK:動態語言工具包;

DSDP:設備軟件開發,調試;

DSDP:設備軟件開發,目標管理;

DTP:數據工具平臺;

ECF:Eclipse通訊框架;

Dash:協作及自動腳本工具;

EMF/EMF-QTV1.1: 模型框架及代碼生成;

M2T:Model-to-Text引擎;

GEF:圖形編輯框架;

GMF:圖形模型框架;

MDT:模型開發工具;

Mylyn:任務集成;

STP:SOA工具平臺;

TPTP:測試及性能工具;

WTP:Web工具平臺。

圖2-6 Eclipse界面

Workbench,工作臺,用於所有窗口的容器。

Perspective,透視圖,用於所有已打開的視圖和編輯器的可視化容器。

View,視圖,顯示特定類型資源的可視化容器,通常包括數據網格或樹結構。

Short Cut Bar,快捷方式欄,圖標集合,允許用戶快速訪問不同的透視圖。

Menu Bar,菜單欄,內容敏感動作的集合,提供執行某些預定義功能的能力。

Tool Bar,工具欄,內容敏感動作的集合,提供執行某些預定義功能的能力。

Editor,編輯器,是用戶顯示和操作數據的主要工具。

2.3.4 Eclipse與OSGi

2003年,Eclipse組織決定將Eclipse原來的插件體系換成OSGi體系。在2004年6月發佈的Eclipse 3.0中,首次採用了OSGi Plug-in架構。

Eclipse中包含一系列服務的模塊即爲Plug-in,Plug-in通常是由Bundle和Service構成。在此基礎上,Eclipse認爲Plug-in之間通常存在兩種關係:依賴與擴展。對於依賴,通過OSGi中元描述信息裏添加需要引用的Plug-in即可實現,擴展在OSGi中沒有定義,Eclipse採用了Extension Point的方式來實現Plug-in的擴展功能。

Eclipse遵循OSGi,對於Plug-in的ID、版本、廠商、類路徑、所依賴的Plug-in以及可暴露對外的接口均在manifest.mf文件中定義。對於擴展,Plug-in可定義自己的Extension Point,也可實現其他Plug-in的Extension Point,由於擴展在OSGi中未定義,所以Eclipse中仍然通過plugin.xml進行描述,所提供的Extension Point通過XML模式的方式描述。

Eclipse在設計時,遵循2個分層法則,即語言層相關和語言層無關的代碼分開(如jdt.core和core),核心與UI(User Interface)分開(如workbench.ui和workbench.core)。在Plug-in的Framework部分,也是如此。Eclipse首先是實現了OSGi Impl,主要通過FrameWork、BundleHost、ServiceRegistry、BundleContextImpl等對象,實現了Bundle的安裝、觸發、卸載以及Service的註冊、卸載、調用。在裝載機制上,Eclipse採用的爲懶加載(lazy load)的方式,即在調用時才進行實際的啓動,採用句柄或實體的方式來實現,外部則通過OSGi進行啓動、停止等動作,各Plug-in則通過BundleContext來進行服務的註冊、卸載和調用。

對於Extension Point,在裝載Plug-in時,Eclipse通過對plugin.xml的解析獲取其中的<extension-point>節點和<extension>節點,並相應的註冊到ExtensionRegistry中,而各個提供擴展點的Plug-in在提供擴展點的地方進行處理,通過這樣的方法,Eclipse實現了對於Plug-in的擴展以及擴展的功能的回調。在Plug-in Framework中還涉及很多事件機制的使用,比如Framework的事件機制,用於在Bundle註冊、Service註冊的時候進行通知。

2.4模型驅動相關理論與技術標準

模型,是爲理解事物而對事物的一種抽象,通常由符號與符號的組織規則構成。模型通過抽象手段描述問題,從而避免陷入具體的技術細節,所以當技術爲適應需求、環境等因素而發生變化的時候,描述問題的抽象模型卻不會變化,從而使得因技術變化而產生的對軟件系統的影響減少。模型也是開發人員與領域人員之間使用相同表達方式進行有效溝通的手段,是彌合技術和業務之間縫隙的有效方法。目前,模型驅動領域由OMG(Object Management Group)MDA主導。

2.4.1 MDA相關標準介紹

MDA,是OMG提出的開發方法,其核心思想是抽象出與具體實現技術無關的描述業務功能的核心PIM,針對不同具體實現技術制定多個映射規則,然後通過這些映射規則及輔助工具將PIM轉換成與具體實現技術相關的應用PSM,最後再由PSM自動轉換成程序代碼。MDA使模型僅需建立一次便可運行於不同的平臺環境之上,分離分析、設計與具體實現技術之間的緊耦合關係,從而使技術變化對系統的影響減少。

圖2-7 MDA架構

MDA是建模相關的一系列規範與標準,主要有統一建模語言UML、元對象設施MOF(Meta-Object Facility)、基於XML的元數據交換XMI(XML-Based Metadata Interchange)、通用數據倉庫元模型CWM(Common Warehouse Metamodel)、模型查詢/視圖/轉換QVT(MOF Query/Views/Transformations)等。

MOF是MDA規範的核心。MOF定義的四層模型幾乎覆蓋了以往所有模型概念與技術。其中,M0層表示真實存在的系統的實體,M1層標識系統的模型,M2層表示模型的元模型,M3層表示元模型的元-元模型,且是自描述的,如UML建模語言處在M2層,而定義UML建模語言的元-元模型即位於M3層了。MOF的元-元模型解決了位於M2層的不同元模型間的交互問題。

圖2-8 MOF層次

目前,EMF(Eclipse Modelling Framework)是MOF比較好的實現,包括建模框架與代碼生成器,使用XMI描述模型,支持多種元模型讀入,包括Rose .mdl、XML Schema、Java Annotation等,最終生成模型的程序代碼與模型編輯器,以支持模型實例的各種功能操作及可視化拖拽式的模型編輯。通常使用XML模式定義元模型輸入EMF。

EMF是Eclipse平臺的子項目,即Eclipse平臺Plug-in架構下的Plug-in,必須結合Eclipse平臺使用。而與Eclipse平臺結合可以使EMF提供更爲良好的開發能力,在Eclipse平臺Plug-in架構的基礎上建立擴展機制,使DSL與建模工具的各個部分可以不斷的演化發展,在提供系統缺省實現的同時可以整合現有的實現,模型轉換開發人員也可以不斷加入新的模型轉換擴展。

UML是一種面向對象的通用建模語言,它由曾經是面向對象軟件建模三種主流語言的The Booch、OMT和OOSE綜合而得,然後被OMG制定爲面向對象建模的標準語言。目前有很多圖形工具支持它,並已得到廣泛的應用。UML定義了多種模型元素,支持對面向對象系統的靜態建模和行爲建模。UML靜態模型包含對類及其屬性、操作、接口的定義和類之間關聯(比如繼承、依賴和包含等)的定義。對系統行爲語義的建模可以用序列圖和協作圖完成。

CWM是OMG在2000年提出的一套關於數據倉庫的標準,其主要目的是爲了方便異質分佈式系統中的數據倉庫工具、數據倉庫平臺以及元數據庫之間的元數據交換,它覆蓋了數據倉庫應用程序的整個生命週期,包括設計、構建以及管理,支持生命週期的管理。

XMI則是一種在不同工具、知識庫和中間件之間使用的標準的互交換機制。XMI的主要作用是用流的方式進行模型交換,因爲OMG採用MOF作爲表示元數據的技術,XMI的重點就是MOF元數據(也就是遵循MOF元模型的元數據)的交換。XMI支持任何能用MOF規範表示的元數據的交換,它不僅可以對整個模型或部分模型組成的元數據進行編碼,還可以對特定工具擴展的元數據編碼。

上述MOF、UML、CWM、XMI等標準構成了MDA的核心技術體系。但MDA在實際應用中存在着諸如不能靈活適應特定領域建模、“兩邊維護”等問題,嚴重製約其本身的發展,所以,目前MDA的研究出現了分支,其中重要的一支便是DSM。

2.4.2 DSM相關概念介紹

DSM與MDA間的最大區別在於“是否領域特定,從而能生成100%的代碼”。

程序語言向着人類認識世界和解決問題的方式的方向發展,即提高抽象程度。抽象程度決定着軟件生產力。高級程序語言並非是對低級程序語言的拋棄,而是兼容,低級程序語言作爲高級程序語言的一個支撐層次而存在。所以單獨的建模語言對提高軟件生產力的幫助並不明顯。

圖2-9 DSM抽象程度

統計表明,從彙編語言到Basic語言,軟件生產力提高了400%,而從Basic往後,如C++、Java,軟件生產力提高不足20%,究其原因何在:抽象程度不夠,而DSM被認爲是提高抽象程度的有效手段。就像高級編程語言隱藏彙編語言,DSM通過提高抽象程度隱藏高級編程語言。

圖2-10 DSM組成部分

DSM通常由三部分組成:DSL及其編輯器、領域特定代碼生成器、領域特定構件庫14。領域特定構件庫形成對領域特定構件的管理,構件通常存在於以往的應用代碼中,如以往高質量的代碼片斷複用爲構件。領域專家結合領域概念與規則,結合領域特定構件庫,建立DSL,並輔以編輯器提高DSL易理解性與易使用性。領域特定代碼生成器根據DSL建立的應用模型結合領域特定構件最終生成完整的可運行程序代碼。因爲領域專家參與定義代碼生成器,使得生成的代碼質量高於手工編寫的代碼質量,更重要的是由於程序代碼可100%的自動生成,從而大大提高了開發效率。

DSM強調生成100%的程序代碼,期望通過積累形成新的程序語言,從根本上提高軟件生產力。模型是爲理解事物而對事物的一種抽象,通常由符號與符號的組織規則構成。建模工具是模型的圖形化表達,增強了模型的易理解、易操作等特性。代碼模板是將模型轉變爲技術實現的手段,是模型到技術實現的中間映射層。模型、建模工具、代碼模板分別通過符號化、圖形化、模板化三個過程實現了抽象程度的提高。

目前,通常通過MOF建立領域特定元模型,並使用GMF(Graphical Modeling Framework)通過快速定製生成特定領域建模工具,通過建模工具建立具體的領域特定模型,而代碼生成器通常結合代碼模板技術生成完整的程序實現代碼。

2.4.3元建模相關概念介紹

軟件開發往往涉及多個領域,而不同的領域往往需要不同的建模語言及其建模工具。但是,手工地爲不同的建模語言開發建模工具代價高昂。元建模技術是解決這個問題的方法之一,通過元建模,可以根據領域需要定製合適的元模型以定義領域建模語言,進而自動生成支持該建模語言的建模工具。

元建模即建立用以刻畫某種建模語言的元模型,並提供支持該建模語言的建模工具15。元建模工具則是支持元建模的輔助開發工具,它可以用於設計建模語言,同時還可以輔助實現支持該建模語言的建模工具。

目前通常EMF描述特定領域元模型,使用GMF快速定製生成各種特定領域建模工具,本文亦採用這種方式來實現特定領域的元建模。

2.5領域工程相關理論

領域工程是爲一組相似或相近系統的應用工程建立基本能力和必備基礎的過程,它覆蓋了建立可複用軟件構件的所有活動16。領域是指一組具有相似或相近軟件需求的應用系統所覆蓋的功能區域17

圖2-11 領域工程中的階段與活動

如圖所示,領域工程包括三個主要的階段:

(1)領域分析,這個階段的主要目標是獲得領域模型。領域模型描述領域中系統之間的共同的需求。這個階段的主要活動包括確定領域邊界,識別信息源,分析領域中系統的需求,確定哪些需求是被領域中的系統廣泛共享的,哪些是可變的,從而建立領域模型;

(2)領域設計,這個階段的目標是獲得領域構架(即特定領域的軟件構架,Domain-Specific Software Architecture,DSSA)。DSSA描述在領域模型中表示的需求的解決方案,它不是單個系統的表示,而是能夠適應領域中多個系統的需求的一個高層次的設計。建立了領域模型之後,就可以派生出滿足這些被建模的領域需求的DSSA。由於領域模型中的領域需求具有一定的變化性,DSSA也要相應地具有變化性;

(3)領域實現,這個階段的主要行爲是定義將需求翻譯到由可複用構件創建的系統的機制。根據所採用的複用策略和領域的成熟和穩定程度,這種機制可能是一組與領域模型和DSSA相聯繫的可複用構件,也可能是應用系統生成器。

綜上所述,領域工程對領域中的系統進行分析,識別這些應用的共同特徵和可變特徵,對刻畫這些特徵的對象和操作進行選擇和抽象,形成領域模型,依據領域模型產生出領域中應用共同具有的體系結構或生成過程,並以此爲基礎識別、開發和組織可複用構件。這樣,當開發同一領域中的新應用時,可以根據領域模型,確定新應用的需求規約,根據特定領域的軟件構架形成新應用的設計,並以此爲基礎選擇可複用構件進行組裝,從而形成新系統。

領域工程有助於產生具有較高可複用性的構件。領域工程將關於領域的知識轉化爲領域中系統共同的規約、設計和構架,使得可以被複用的信息的範圍,擴大到了抽象級別較高的分析和設計階段。由於通過領域工程產生的可複用構件來源於領域中現有的系統,體現了領域中系統的本質需求,因此這些構件具有較高的可複用性。

同時,領域工程產生了領域模型和DSSA或應用系統的生成過程,這對於基於複用的開發很有幫助。可複用構件是根據領域模型和DSSA組織的,方便了構件的檢索。開發以領域模型和DSSA爲線索進行,可以幫助開發者識別複用機會,判斷可複用構件是否符合當前需要。爲構件組裝提供了上下文,使得利用可複用構件組裝或生成新的系統較爲容易。

圖2-11 一種基於領域工程的開發方法

如圖所示,基於領域工程的開發方法,按照領域架構確定搭建特定領域系統所需要的可複用構件,根據特定領域系統的特定需求對系統架構以及所需要的可複用構件進行特化,並形成特定領域的專用構件,然後將特定領域架構、特定領域構件以及系統專用構件組裝爲完整系統。

基於領域工程的開發方法是以構件組裝爲主的軟件開發過程。

2.6本章小結

本章主要介紹了本文研究的相關理論與技術,着重分析了構件組裝的發展過程以及構件組裝理論的本質與其數學基礎,着重分析了偏重於運行時構件組裝的SOA與OSGi相關理論與技術,着重分析了MDA與DSM之間的區別以及元建模的相關概念,介紹了領域工程中的各個階段與活動及其之間的關係。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章