newland.js之所以是架構而不是類庫,最重要的原因是它只要幾步就能建立起一個網站!換言之,它已經包含了網站從啟動到啟動並執行重要流程,至於你還需要什麼,是制定還是完善等等不確定的東西,架構已經預留了位置給你填空了。
架構讓程式員變成流水線上的工人這一事實是無法復原轉的,唯一的區別的有的流水線非常智能,讓你過得非常愜意,有的則非常噁心,讓你變成苦逼的碼畜!
JAVA的三大架構之一,Spring最偉大的舉措就是發明了IoC容器。是的,架構幫你做了許多事,但有些檔案還是要你去建的,建在指定的目錄下;有些代碼你還要去寫,依照規定好的格式,是建哪個類,繼承哪個父類,差一步也不行。架構帶來便捷的同時,也帶來的枷鎖!IoC的目的是讓這些痛苦減少些!
首先抄一段話解釋什麼叫IoC——“在依賴注入的模式下,建立被調用者的工作不再由調用者來完成,因此稱為控制反轉;建立被調用者執行個體的工作通常由容器來完成,然後注入給調用者,因此也稱為依賴注入”。
在我的newland.js架構中,最開始的mass.js模組其實只是提供模組載入機制與一些通用方法,不幹正事的,它唯一做的有意義的是調用了mvc這個模組。
$.require("system/deploy,system/mvc", function(deploy){ deploy( process.cwd() );//監聽app目錄下檔案的變化,實現暖開機 });
mvc模組的作用是啟動服用器,接受請求!在此之前,它會讀取設定檔,把使用者指定的攔截器與預設攔截器與所有控制器統統讀入記憶體,裝配到系統中!
所謂的欄截器其實就是structs那套東西,不認識JAVA的同學如果懂node.js,就去看看connectjs的中介軟體,差不多就是這個意思,用於處理請求與響應用的工具包。
而控制器是重點,MVC不能沒有它。一個控制器有許多功能,因此我們把共用的功能抽取出來構建成基類, 而我們所建的控制器作為子類繼承它就可以節約許多代碼。
//遍曆app/controllers目錄下所有控制器模組,並與攔載器模組一起載入它們!$.walk("app/controllers", function(files){ $.require( inter.concat( files ), function(){ //攔截器放在最前面 var intercepters = [].slice.call(arguments,0, inter.length); resource_ready( intercepters ) }); });
在沒有用IoC之前,我們的控制器是這個樣子的:
.define("doc_controller",function(){ var klass = $.factory({ inherit: $.base_controller, index: function(flow){ $.log("已進入doc#index action"); flow.session.set("xxx","in doc") var view_url = $.path.join("app","views", flow.req.url ); flow.fire("get_view", view_url, flow.req.url ) } }); $.controllers[ "doc"] = new klass});
其實使用者要寫的就是index,show, edit, destroy這樣action方法,其他部分就是死格式!什麼指定父類,new執行個體其實交給系統去處理就行了!因此我們的自訂控制器可以削減成這樣子!
$.define("doc_controller",function(){ return { index: function(flow){ $.log("已進入doc#index action"); flow.session.set("xxx","in doc") var view_url = $.path.join("app","views", flow.req.url ); flow.fire("get_view", view_url, flow.req.url ) } }});
那麼子類的建立與繼承關係的指定與執行個體的建立傳到mvc.js中去管理:
var rcname = /\/(\w+)_controller/; //遍曆app/controllers目錄下所有控制器模組,並與攔載器模組一起載入它們! $.walk("app/controllers", function(files){ $.require( inter.concat( files ), function(){ //取得放在前面的攔截器 var intercepters = [].splice.call(arguments, 0, inter.length); //取得放在後面的控制器 var controllers = arguments; //進行控制反轉,構建我們所需要的控制器子類與它的執行個體 files.forEach(function(el, i){ //mac下的路徑為 app/controllers/doc_controller.js //window下的路徑為 app\\controllers\\doc_controller.js var match = el.replace(/\\/g,"/").match(rcname); var controller = controllers[i]; controller.inherit = $.base_controller var klass = $.factory(controller); $.controllers[ match[1] ] = new klass; }); resource_ready( intercepters ) }); });
需要說明一下的是,newland.js分成兩大塊,app目錄下的模組是使用者自建的檔案或系統指令下建立的模組(下稱app模組),system目錄下的模組則是輔助app模組運行用的。需要使用者動手的app模組越簡單就越好!任何複雜的類最好不要用,就算用都交由架構去處理,去new 執行個體;任何複雜的功能都做用鉤子的形式,或通俗地說,是回呼函數的形式,交由架構去調度;所有不確定的功能都做成自訂事件形式,由架構或架構的另外載入的模組去fire。諸如此類,所有耦合就鬆綁了,得以最大限度地適應需求的變化。
http://dotnetfresh.cnblogs.com/archive/2005/06/27/181878.html