雙mvc框架

雙mvc框架

[\1/]新寫的lua mvc 框架,支持4種mvc 寫法:

1、可以按照傳統mvc(pureMVC)來寫,但是command要寫在控制器裏面,因爲框架的控制器和視圖基類都是抽象了消息列表接口;mediator現在是兼中介者和視圖邏輯,就是不必組合的視圖最後的視圖邏輯都放mediator裏面,因爲遊戲不是強組件特質,遊戲應該更多樣

2、控制器ctrl和view 都不使用事件機制,就是簡單mvc的形式,之間通訊用調用接口(函數)的形式,有一個單獨的網絡層,負責發送和接收消息,model在這裏沒有了(組織數據都在ctrl),數據都存在ctrl 裏面用表或其他結構簡單的表示

3、控制器ctrl和view 都不使用事件機制,就是簡單mvc的形式,之間通訊用調用接口(函數)的形式,model層組織數據和訪問網絡,model就是域邏輯,model就是一個遠端代理,model層只對外提供數據獲得接口,這裏model其實就是傳統mvc的model(只是不是通過發消息通知其他層,沒了消息模式),model對象不會引用到其他ctrl 或者 view,ctrl或者view 在使用model的時候註冊回調函數

4、控制器ctrl和view 都不使用事件機制,就是簡單mvc的形式,之間通訊用調用接口(函數)的形式,有一個單獨的網絡層,負責發送和接收消息,data對象組織數據(也提供查找數據的方法),被ctrl持有,並且view也可以使用,data對象不調用ctrl或者view的方法([\4/+=2]data對象不包含業務邏輯)

5、當然這樣的框架混合寫纔是最好,用傳統mvc寫遊戲核心部分,用簡單mvc寫其他次要系統,最推薦的簡單mvc寫法是(2、),(3、)其次,(4、)在lua裏面顯得略臃腫

6、這裏(3、)的簡單mvc模式之所以model不直接引用到ctrl或者view,是因爲如果引用到,那麼這種寫法和(2、)或(4、)的寫法就沒差別了,數據不是在model就是在ctrl 或者單獨建個文件,還不如選一種(2、)或者(4、)的寫法(一個系統的協議很多,如果協議沒封裝就很多函數,model層看起來就很龐大了)。model不引用到其他層對象,其他層改變不會影響到model層,並且這樣也利於思考(邏輯可以很直觀的分爲域邏輯和事務邏輯)。雖然model直接引用(調用)ctrl或者view的形式邏輯也是分爲域邏輯和事務邏輯,但是model不引用到其他層對象的時候,即便model對象變得很龐大了,修改控制層(ctrl)代碼的時候也會變得容易些。修改控制層(ctrl)也是很經常的。

[/2+#+=2]寫法(1、)(2、)(3、)(4、)(5、)和分析(6、)都是重要的

[/3+#+=2]分析(6、)是確定的

[/4]Command可能被用於實現一些複雜、必須按照一定順序的系統行爲,上一步動作的結果可能會流入一下個動作。(引用自《pureMVC》,這就是業務邏輯)

[/1] 
enter image description here

AppExtBase 中的派發消息接口 
title

AppExtBase 中註冊和移除 控制器、模型接口 
title

AppExtBase 中註冊和移除 視圖接口 
title

ControllerBase 
title

ViewBase 
title

ModelBase的get和set接口,有隻讀屬性才使用它,因爲這個是方便寫應用的(組件式的寫法要用到),要明瞭的聲明類實例的屬性也可以用它([\10/]明瞭的聲明類實例的屬性) 
title

[/10] 
title

[/11+=2]寫法3在model註冊回調的時候,model支持註冊一組回調(model依次調用),這樣它其實就是向下兼容的,你只註冊一個回調也可以。例:角色hp過低,血條會變化、屏幕也會閃爍;這就是多個回調的情況。

[/12+=2]其他寫法的ctrl或者view也不應該被model引用(這個model指寫法3的model);如果其他系統是在這個系統之前開發,那麼調用接口(model引用到其他寫法ctrl或者view)也不錯,因爲這個時候其他已寫好的系統改動就不是經常的了([\15/]通常已寫好的系統重構也可以兼容接口,即使服務端重構也可以兼容接口來重構,因爲系統的行爲通常不變(除非策劃改了))。

[\12/+/13+=2]如果在寫當前系統的時候也用適配接口的方法來達到不修改model的目的(寫法3),這樣容易產生不良代碼(不易讀或者邏輯複雜的代碼),不安全。

[/14+\12,13/+=2]所有系統、所有層的接口都應該是一個標準接口(規範化的接口),這樣依據數學模型的接口才能發揮多態的強大。

[/15+\14,12/+=2]如果重構的系統接口行爲有所差異了,並且依據原有行爲接口兼容形式的寫法會帶來較大的性能損失,那麼筆記12的兼容接口重構是不適用的。

  1. [\11/+/16\+正常運行]
  2. //>>>>>>>>>>>>>
  3. --
  4. -- Author: xiaowa
  5. -- Date: 2015-10-17 07:53:29
  6. --
  7. --框架回調對象
  8. local CallBack = CallBack or class("CallBack")
  9. local call_hash_ = call_hash_ or app.util.HashMap.new()
  10. --e_name 註冊回調的事件名
  11. function CallBack:ctor(e_name)
  12. self.e_name_ = e_name
  13. call_hash_:setElement(e_name,self)
  14. end
  15. function CallBack:call(...)
  16. local n = table.getn(self)
  17. for i=1,n do
  18. self[i](…)
  19. end
  20. end
  21. function CallBack:register_call(fun)
  22. table.insert(self,fun)
  23. end
  24. function CallBack.register(e_name,fun)
  25. local callback = call_hash_:getValue(e_name)
  26. callback:register_call(fun)
  27. end
  28. return CallBack
  29. //<<<<<<<<<<<<
  30. [/17\+正常運行]
  31. //>>>>>>>>>>>>>>>>>>
  32. function LoginCtrl:ctor()
  33. --測試回調對象
  34. self.print_ = app.compose.CallBack.new(TEST_CALLBACK)
  35. end
  36. function LoginCtrl:enterLoginScene()
  37. self.login_view_:open()
  38. self.print_:call("this is callback on LoginCtrl")
  39. end
  40. TEST_CALLBACK = "test_callback"
  41. function LoginView:open()
  42. display.replaceScene(self.scene_)
  43. local num = 1
  44. local function fun1(str)
  45. printLog("xiaowa",str.." in "..num)
  46. num = num+1
  47. end
  48. local function fun2(str)
  49. printLog("xiaowa",str.." in "..num)
  50. num = num+1
  51. end
  52. app.myApp:register(TEST_CALLBACK,fun1)
  53. app.myApp:register(TEST_CALLBACK,fun2)
  54. end
  55. //<<<<<<<<<<<<<<<<<

[\16,17/+=2]筆記16、17是註冊回調的代碼,回調只能註冊,不能刪除,這樣回調就像直接調用的形式;回調需要定義全局事件名;如果想用能刪除的形式,請用事件。

[/18+=2]最後,那個ModelBase基本沒用(只讀屬性在尾部加”_”,自己寫get方法),要麼留一個空ModelBase類,要麼就不繼承直接寫Model類。


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