CodeIgniter 框架擴展:HMVC
CodeIgniter 框架擴展:HMVC
Hierarchical((階層式的))-Model-View-Controller(HMVC)模式,也可以叫做 Layered MVC。
Hierarchical((階層式的))-Model-View-Controller(HMVC)模式,也可以叫做 Layered MVC。
為什麼需要 HMVC
單層 MVC 的限制
原 MVC 架構中只有單層 MVC
,單層 MVC 的設計本身沒問題,但隨著系統功能漸變多變複雜時,程式碼卻只能塞進單層 MVC 裡面,程式碼很快就會變得 巨大、縱錯複雜、互相耦合、難以維護。試想一下,一個 Controller 內有 7、8 千行程式碼會容易維護嗎。原 CodeIgniter MVC 架構(單層 MVC)示意圖:
application
|- controllers
|- controllersA.php
|- controllersB.php
|- ...(所有 Controller 都只能放在同一層)
|- models
|- models1.php
|- models2.php
|- ...(所有 Model 都只能放在同一層)
|- views
|- views1
|- index.php
|- footer.php
|- ...
|- views2
|- index.php
|- footer.php
HMVC 帶來的解決方案:
擴展 MVC 架構,
使用模組好處是:
讓 MVC 底下可以再擴充一層或多層子 MVC
,讓單層 MVC 變成階層式 MVC,而這些擴充出來的 MVC,又稱作為模組、模塊(Modules)。使用模組好處是:
- 使每個功能都可以獨立出來
- 因模組變得獨立,降低各個功能模組之間的耦合性
- 提高程式碼複用性
- 每個模組都有自己的 MVC 結構
HMVC 架構示意圖:
CodeIgniter HMVC 擴展模組後,其結構(階層式 MVC)如下:
application
|- modules
|- moduleA
|- controllers
|- controllers.php
|- models
|- models.php
|- views
|- index.php
|- footer.php
|- ...
|- modules (模組 A 底下還可以有子模組...)
|- controllers
|- moduleB
|- controllers
|- controllers.php
|- models
|- models.php
|- views
|- index.php
|- footer.php
|- ...
|- modules (模組 B 底下還可以有子模組...)
|- controllers
|- ....
|- controllers
|- ...
|- models
|- ...
|- views
|- ...
真實使用情境:
只有單層 MVC 架構的情況下,這些功能的程式碼都必須寫在同一個 Controller 裡面。因此 單層 Controller 會在很短的時間內便得龐大又複雜。
在 HMVC 架構中,則可以把這些功能全部拆分成
這麼做 減輕了單層 Controller 對每個功能模組的耦合。拆出去的模組也變得高內聚,且模組的功能變得更容易複用。
表單管理
底下的模組。這麼做 減輕了單層 Controller 對每個功能模組的耦合。拆出去的模組也變得高內聚,且模組的功能變得更容易複用。
表單管理 HMVC 模組結構
不斷地抽象、封裝
HMVC 可以說是物件導向程式設計的體現。
一個良好的物件導向系統,會隨著程式碼的複雜度上升與變化增加,不斷的進行抽象、封裝。
抽象是將一系列相關的程式碼做歸納,目的是降低人類的認知超載。
而封裝是抽象過程中的一種技術,且物件導向開發傾封裝複雜的過程,以便重複利用。
而封裝是抽象過程中的一種技術,且物件導向開發傾封裝複雜的過程,以便重複利用。
如果不做抽象會怎樣?嘗試一下下面的範例
// If url is an object, simulate pre-1.5 signature
if (typeof url === "object") {
options = url;
url = undefined;
}
// Force options to be an object
options = options || {};
var // Create the final options object
s = jQuery.ajaxSetup({}, options),
// Callbacks context
callbackContext = s.context || s,
var // Create the final options object
s = jQuery.ajaxSetup({}, options),
// Callbacks context
callbackContext = s.context || s,
// Context for global events
// It's the callbackContext if one was provided in the options
// and if it's a DOM node or a jQuery collection
globalEventContext = callbackContext !== s &&
( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
jQuery(callbackContext) : jQuery.event,
// Deferreds
deferred = jQuery.Deferred(),
completeDeferred = jQuery.Callbacks("once memory"),
// Status-dependent callbacks
statusCode = s.statusCode || {},
// ifModified key
ifModifiedKey,
// Headers (they are sent all at once)
requestHeaders = {},
/**
* ajax 全長有 380 行程式碼,故省略。
**/
上面這段程式碼都是「實作」非同步連線功能的程式碼。
而 jQuery 將這段程式碼
如果每次使用非同步連線功能都要寫 380 行程式碼,那真的會瘋掉。
而 jQuery 將這段程式碼
抽象成大家熟悉的 $.ajax
。如果每次使用非同步連線功能都要寫 380 行程式碼,那真的會瘋掉。
HMVC 除了封裝以外,又讓模組享有 MVC 的功能
HMVC 不只是單純的進行抽象,也讓每個模組享有 MVC 架構的功能!
留言
張貼留言