設計模式綜和實戰項目x-gen系列一

1 X-gen的項目背景

1.1 項目背景

很多做應用項目的朋友都會有這樣的感覺:項目越來越大,模塊越來越多,但是大多數都是重複或者相似的做法,至少每個模塊的基礎部分的實現是差不多的,比如CRUD(增刪改查)功能的實現,又比如翻頁功能的實現等等。

因此,很多朋友都在想辦法解決這個問題,如何能夠減少這些重複勞動,讓自己把有限的時間和精力投入到具有創意或挑戰的功能實現上。

很快地,大家便根據自己的需要,結合公司已有的系統架構和公共功能,製作出了符合自己需要的小應用,可以實現根據配置文件或者是數據庫定義來生成應用模塊,並帶上增刪改查的功能實現。

通常的實現思路是,先根據本公司實現增刪改查的方式來製作模板文件,然後把模板裏面需要變化的部分改成變量,然後通過配置文件去配置這些需要變化的值,然後在程序運行的時候,由程序去讀取配置文件的值,把這些值替換到模板中,從而得到需要生成的文件,然後把生成好的文件輸出出來就好了。

一切看起來是那麼完美,從此不需要再去寫每個模塊的基礎部分了,可以根據配置或數據庫定義來生成這些基礎部分,然後在此基礎之上,進行業務功能的開發就可以了。

通常這種程序,由於是公司內部專用,因此會實現得非常簡單,很多複雜多變的狀況也就不再去考慮了,只要滿足自己的需要即可。

1.2 面臨的問題

看上去很不錯吧,但是真的很完美了嗎?考慮一下如下的問題:

Ø如果生成的配置文件需要發生變化
那麼相應的讀取配置文件的程序需要變化;同時使用這些數據的程序也需要變化

Ø如果模板文件需要發生變化
那麼讀取模板文件的地方需要發生變化,同時,運行中把參數數據設置到模板的程序也需要發生變化。

Ø如果調用邏輯或調用順序需要發生變化
那就需要修改調用部分的程序來適應新的變化

Ø如果輸出格式需要發生變化
那就只好重新寫代碼來實現新的輸出格式

類似這樣的問題還有很多,這裏就不一一列舉了。

由於很多這樣公司內部使用的工具型應用,是按照公司現有的開發模式來實現的,大都實現得非常簡單和僵硬,對於這些變化適應能力是非常差的。

而上述這些變化,是經常發生的,因此,很多公司都會有人專門負責維護這樣的內部應用,不斷更改這些程序來適應新的應用的需要。

而且,由於生成的調用過程、生成配置、生成模板以及最後生成文件是攪和在一起的,因此改動起來非常困難。

1.3 X-gen出場

因此我們需要一個項目,來把生成應用的核心部分獨立出來,形成公共的應用,讓變化的部分從應用中分離出來,讓程序人員可以根據需要進行配置和擴展,從而適應各種應用的需要。

X-gen就是這樣一個應用。X-gen分成兩個部分,一個部分是核心框架,用來實現生成應用的公共部分;另外一個部分就是自定義模板部分,按照程序人員的需要來制定模板,幾乎所有能重複使用的功能都可以通過X-gen生成,沒有什麼使用限制。

注:由於中文表達中存在很多歧義,比如:“生成應用配置”,到底是說產生應用的配置文件呢?還是指的x-gen這個生成應用的配置?因此,本書後面提到生成應用的時候,都以x-gen來代替。某些地方提到生成的時候,爲避免歧義,用“generate”來代替。

2 系統功能

2.1 系統整體功能概述

x-gen是一個能按照模板和配置去生成結果的通用框架,設計精巧,結構靈活,平臺開放,支持模板自定義,支持配置方式自定義,支持生成方式自定義,甚至可以自定義generate的過程。X-gen的核心是一個通用的生成調用框架,本身並不約定任何需要生成的東西,因此幾乎可以滿足所有朋友的各種generate需求。

x-gen首先要解決根據什麼來生成的問題;其次要解決如何生成的問題,同時還要解決在生成的時候如何利用外部主題的問題;然後要解決生成結果的問題,包括最終生成成爲什麼格式,以及把結果輸出到什麼地方等問題。

2.2 配置管理(genconf)功能概述

x-gen是按照配置來generate的,因此對於x-gen,配置是非常重要的一個部分。

X-gen是一個通用的框架,它本身並不固定要求配置的格式,也不要求配置的來源,因而它也不固定獲取和解析配置數據的程序。雖然x-gen默認提供了對xml配置的支持,但是可以通過註冊新的provider來提供對新的配置方式的支持。

x-gen可以完全由開發人員自己來制定配置的方式、配置的地方、配置的格式,以及如何獲取這些配置數據,如何解析這些配置數據等。並能夠以很簡單的方式插接到x-gen的核心框架中。

2.3 分發調度(dispatch)功能概述

分發調度提供接受用戶請求的入口,然後根據用戶請求的內容,去獲取相應的配置數據,獲得戶配置的數據過後,就按照配置的要求來發出命令,要求按照這些配置數據來完成generate的功能。

在每一個具體命令的實現中,先動態組合需要完成的generate的功能,然後就把這些功能交給generate的代理去完成。

也就是說分發調度只是負責接收用戶的任務,然後把任務組合好,最後分配出去這些功能,只是起到一個調度的作用,本身並不處理用戶的請求功能。

2.4 生成代理(genproxy)功能概述

生成代理是一個介於生成調度(dispatch)和真正生成(geninvocation)之間額外的附加層,目的是能夠根據需要切換不同的代理,比如生成調度根據配置,需要通過遠程來生成,那麼就需要遠程代理,遠程訪問的方式可能是rmi或webservice等等

2.5 具體調用(geninvocation)功能概述

首先根據用戶配置的數據去獲取相應的theme的數據,然後根據用戶配置的theme的調用過程,用戶配置的generate處理的程序來進行具體的generate。通常是把用戶配置的參數數據,按照一定的規則與theme的模板相結合,從而得到需要生成的結果。

但是這整個過程是開放的,可以由開發人員根據自己generate的需要來配置,從而動態的運行整個generate過程。

2.6 模板管理(template)功能概述

x-gen本身是按照模板和配置來生成,那麼模板怎麼來呢?

x-gen的核心框架本身不綁定任何模板,而是支持模板的自定義,通過插件形式,把用戶自定義的模板結合到x-gen裏面來。

由於模板的配置會有很多個,通常會把多個相關的模板組合在一起,統稱爲主題,也就是theme,今後我們就不說模板了,而是說x-gen根據主題/theme來生成。

目前x-gen缺省提供一個示例性質的simple主題。

模板管理的功能就是負責獲取相應的模板數據,並對這些模板的數據進行管理,在外部需要這些模板數據的時候,可以訪問模板管理提供的接口來獲取。

對於模板的格式,目前x-gen規定固定是文件;對於theme自身的配置,目前x-gen規定固定是xml格式,並由x-gen提供默認的解析程序,這主要是爲了讓theme更好的實現“即插即用”的功能,而且也確實沒有必要讓theme的配置有很多的形式,theme的配置跟theme是緊密聯繫的。

2.7 生成輸出(output)功能概述

具體調用(geninvocation)運行完成後,會產生generate的結果,這些結果如何輸出?輸出到什麼地方?輸出成爲什麼格式等等問題,都由生成輸出來負責。
生成輸出本身並不固定任何的輸出要求,開發人員完全可以在外部來定義輸出的格式,輸出的地方,以及如何輸出等,只需要最後在theme的配置中註冊新的outtype即可。目前x-gen提供了最簡單的輸出成爲普通文本類型的文件的功能。

3 外部主題功能概述

3.1 外部主題功能概述
外部主題是獨立於x-gen核心框架之外的,完全由開發人員根據需要來制定,通常裏面會包含generate所需要的所有原始模板文件,跟模板文件對應的解析和生成的輔助程序,生成處理的Action處理程序,還有theme的配置文件,一般這幾個是必不可少的;其次是根據需要,由開發人員擴展的功能,比如:在進行生成處理前後需要額外添加的功能,自定義的輸出類型等等。
外部主題決定了按照什麼來生成、如何生成以及生成成爲什麼東西的具體信息,是提供給x-gen核心框架使用的重要數據。

4 模塊劃分

根據前面的功能描述,可以把x-gen分成如下模塊:

1:配置管理模塊

(1)模塊邊界
不管配置數據從何而來,不管如何獲取配置數據,只管根據provider得到配置數據,然後緩存管理這些數據,並對外提供訪問這些數據的接口,另外配置管理的配置數據的對象結構是固定的,由x-gen預先定義好,也就是數據的來源任意,但是最終的結果對於x-gen來說是一樣的。
默認提供一個讀取xml配置文件的provider實現。
(2)輸入輸出
輸入:
由theme或者是由x-gen的客戶端來提供provider;由開發人員確定三類配置的配置數據。
輸出:
模塊外部通過接口來訪問配置的數據。

2:分發調度模塊

(1)模塊邊界
不關心配置數據如何得到,也不關心究竟請求要求的功能如何執行。只是負責接收用戶請求,把請求轉化成要執行的功能,然後通知代理去執行這些功能。
(2)輸入輸出
輸入:
客戶請求,可能會傳入可以獲取核心框架配置的provider;所需的配置數據來自於配置管理模塊。
輸出:
把需要generate的功能告訴生成代理

3:生成代理模塊

(1)模塊邊界
不關心配置數據如何得到,不關心要執行些什麼功能,也不關心究竟這些功能如何執行。只是負責根據分發過來的任務,代理調用真正執行生成的模塊。
(2)輸入輸出
輸入:
分發調度模塊分發過來的任務,當然會帶着所需的配置數據和具體的命令。
輸出:
代理啓動真正負責執行生成的模塊。

4:具體調用模塊

(1)模塊邊界
不關心配置數據如何得到,不關心要執行些什麼功能,也不關心究竟這些功能如何執行,更不關心執行完的結果如何處理。

只是負責根據按照核心框架制定的具體調用的功能步驟,依次調用執行,當然過程中會需要使用模板的數據,然後負責在generate過後,通知生成輸出模塊進行輸出。

(2)輸入輸出
輸入:
生成代理模塊傳遞過來的任務,當然會帶着所需的配置數據和具體的命令;以及開發人員擴展的生成的Action處理、以及Action執行前後的裝飾器功能;會通過模板管理模塊去獲取模板的數據。

輸出:
有了generate結果後,自動通知生成輸出模塊進行輸出。

5:模板管理模塊

(1)模塊邊界
不關心模板數據被如何使用。只是按照x-gen的約定,從theme中讀取相應模板的數據,然後把這些數據緩存起來,並提供模塊外部訪問這些數據的接口。

(2)輸入輸出
輸入:
配置中需要的theme的模板文件的路徑。
輸出:
提供模塊外部訪問這些數據的接口。

6:生成輸出模塊

(1)模塊邊界
不關心需要生成什麼數據,也不關心具體生成到哪裏、生成成爲什麼格式以及如何真正實現輸出。只是按照配置中的約定,執行相應的負責生成輸出的對象的方法,把從具體調用模塊傳遞過來的數據生成出去。

(2)輸入輸出
輸入:
配置中相應的數據;具體調用模塊傳遞過來的數據。
輸出:
最終用戶想要生成的結果。

7:公共工具模塊

模塊邊界
跟具體業務不相關,只是提供某些工具性的功能,比如:文件的讀寫、xml文件的通用讀取等等。

說明:本文由微信公衆號——架構設計一起學推出

點擊“閱讀原文”,將有更多收穫哦!

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