1. 程式人生 > >MVC的發展與應用總結

MVC的發展與應用總結

XML ble r.java 重復 操作符 設計與實現 winform 定制 思考

1、 最初的程序都是是命令行界面,後來進化到GUI(Graphic User Interface),即圖形化用戶接口。以一個計算器軟件為例,一個程序無論C/S還是B/S結構都需要搞定:

  a) 界面布局。整個計算器界面要怎麽布局看起來才合理、美觀。

  b) 業務邏輯。例如用戶點擊“=”按鈕時,根據輸入計算輸出結果。

  c) 界面交互。例如用戶點擊“=“按鈕後,界面有什麽響應,如顯示結果以及結果顯示位置等。

  無MVC的情況,如winform在一個Form中,即有計算器的界面顯示代碼,也有觸發監聽器後的流程控制邏輯,還有功能邏輯計算代碼,這三者攪合在一起,程序復雜了後,代碼長度驚人,修改、擴展、閱讀他人代碼都是問題。

2、 桌面GUI程序的MVC設計模式。

  符合“低耦合,高內聚“的軟件工程理念。表現在哪裏?在於MVC將界面顯示代碼跟業務邏輯代碼有效隔離,將原先糅雜一起的代碼分開,各部分趨於專門化,功能職責單一。這樣讓程序更易閱讀、維護、擴展了。

  技術分享圖片

  a) View:負責界面顯示。

  b) Controller:負責View、Model、Service之間的交互、控制業務流程。不涉及具體的業務功能代碼。在桌面端Controller可以是組件監聽器的匿名實現類。

  c) Model:簡單的數據模型,封裝View中的數據,以便於在其他層中的傳遞和使用(以對象的形式)。是數據模型,並不是業務模型,也不涉及具體的業務功能代碼。

  d) Service:封裝了業務邏輯,專門實現業務功能的,如程序功能實現、數據庫操作、第三方庫調用等。在這裏專門把Service標註出來,是為了強調Model僅僅是數據模型,Controller是流程控制,他們都不含業務功能代碼,業務功能代碼集中在Service層。

  桌面MVC的實現。MVC把界面顯示集中在View層,功能實現放在Service層,再在他們間封裝出Model以便數據共享,和Controller層調和各層的交互及流程控制。這樣,就實現了顯示與業務的分離。

  技術分享圖片

  1) View與Model應用觀察者設計模式,一方面View從Model中獲取數據渲染後呈現給用戶,另一方面當Model被修改後能自動刷新到View中並顯示出來。

  2) View與Controller可以應用策咯模式,增加程序靈活性。

  3) Controller組合Service(面向接口)和Model。

               一個java Swing使用MVC的例子:

public abstract class View{

public void update();

}

public class ViewImpl extends View{

//View的界面元素屬性。

Model model;//應用觀察者模式

Controller controller;//組合,可以用策略模式

public ViewImpl(){

model = new ModelImpl(this);

controller = new Controller(model)

//界面布局方法調用,初始化組件方法調用(用model中數據)

}

xxx.addActionListener(new actionlistener{

@Override

public void actionPerform(){

//將界面組件數據刷新到model中

controller.do1();

}

})

@Override

public void update(){

//更新model中的數據到View的界面組件中。

}

}

public interface Controller{

public void do1();

public void do2();

public void do3();

}

public class ControllerImpl implements Controler{

Model model;

public Controler(Model m){

model = m;

}

@Override

public void do1(){

//從model對象獲取數據

//執行業務邏輯和流程

//結果更新到model

////其他一些功能調用和流程控制。

model.notifyView();

}

}

public interface Model{

public void notifyView();

}

public class ModelImpl{

//模型屬性等

View view;

public ModelImp(View v){

view = v;

}

public void notifyView(){

view.update();

}

}

public class Application{

public static void main(String[] args){

//用戶登陸及驗證通過後

View viewImpl = new ViewImpl();

view.visable=true;

}

}

目錄結構:這樣,1)符合面向接口編程(Controller和Model)和面向抽象編程(View),將設計與實現分離。2)每一個Form都由View、Controller、Model三個文件組成,功能劃分清晰,職責單一,便於開發維護。

|-Form

|-View.java

|-Controller.java

|-Model.java

|-ViewImpl_1

|-ViewImpl.java

|-ControllerImpl.java

|-ModelImpl.java

|-ViewImpl_2

|-ViewImpl_3

|-Service

|-Dao

|-DBUtilies.java

|-UserDao.java

|-Impl

|-UserDaoImpl.java

|-entity

|-user.java

思考:MVC只是一個設計思想,實現方式多樣。

1)上面這種方式,每一個頁面從原來的糅合一起到劃分成三個頁面,讓職責單一,便於開發維護。但很明顯額外多出很多文件出來,當程序規模不大時是否還要這樣一分為三? 2)上面View與Controller,Controller與Model他們之間是組合關系,是否可用策略模式,讓View根據不同情況使用不同Controller?

3)上面通過View的監聽器的作用只是調用Controller,真正的流程控制、功能調用在Controler中實現,可不可以直接用監聽器的匿名實現類做Controller,而減少額外的Controller文件?那麽考慮用Controller類做監聽器的實現類又如何呢?

4)創建對象的方式,是否考慮工廠設計模式,進一步解耦?還有可見性的問題,Controller只可見Model和Service,那要控制View的狀態怎麽辦,是否需要封裝其他工具類?這些問題用Spring Ioc解決怎麽樣?還有dao模塊用Mybatis怎麽樣?

5)Controller中既要處理功能調用又要處理頁面交互,一般可以單線程,先控制功能調用,調用後把結果存到Model,最後控制View顯示界面和model數據。可不可以多線程,可不可以把功能調用和頁面交互異步處理?那又是否需要同步呢?

3、 web端程序的MVC模式。

  後來B/S結構的程序開始慢慢發展,從靜態網頁到動態網頁。先說不使用MVC設計模式的情況,如java ee中,僅用jsp做開發。那麽一個jsp頁面中即有html、css、js組成的可視化界面顯示,還有流程控制代碼,以及訪問數據庫等的java程序片。為了解決開發的復雜性,同樣在B/S中使用MVC設計模式。

  技術分享圖片

              (典型的jsp+servlet+javaBean實現MVC)

web的MVC模式與桌面端MVC原理一樣,不過在實現上有很大不同,特別是Model層了。兩者的Model層在功能上是一樣的,都是簡單的封裝對象。

實現上,前面說過桌面端View與Model是觀察者模式,View從Model中獲取數據渲染後呈現給用戶,同時當Model被修改後能自動刷新到View中並顯示出來。而web端MVC中是依賴容器對javaBean組件的支持。jsp和Servlet中按規則使用javaBean,web容器提供一致性支持,servlet修改javaBean的屬性後,當響應用戶jsp頁面時,從javaBean組件中渲染數據到頁面並翻譯成html返回。

有兩個問題:1)、javaBean的使用方式。直接使用,jsp頁面用<jsp:UseBean />標簽,servlet用new操作符。間接使用,還可以通過內置對象Request等傳輸。這兩種方式依然歸於上面Model,因為它的本質沒變。

2)、從本文開始到現在,我還是認為MVC中的Model只是簡單的數據模型,而不是有的博客上說的jsp做界面,servlet做流程控制,javaBean處理業務邏輯。MVC本質上是為了解耦界面顯示(如jsp)與業務邏輯(如service),獨立出Controller控制流程和各層的交互,再添一個Model層解耦View和Controller。

4、 其他MVC開發框架SpringMVC

  上面javaEE原生組件jsp+serlet+javaBean已經可以用MVC模式開發web程序。那為什麽大多後臺開發都用SpringMVC、Struts2這些開發框架呢?

  技術分享圖片

  1) javaEE原生組件雖然對程序開發提供了支持,但面對現在多變的需求,開發過程繁雜,重復代碼多。而SpringMVC等提供了封裝更好的組件與環境支持,能更快、更簡潔用於程序開發。從上面明顯看出,組件間耦合性更低了。特別是通過springMVC把View層和其他層分離,讓程序真正前後端分離了。

  2) springMVC框架提供了更靈活的程序架構,更適應現在程序開發的多變。如不止可以響應用戶jsp頁面,還可以返回json、xml、excel、pdf等。

  3) SpringMVC框架,還可以自由地選擇與其他框架搭配整合,如spring、mybatis等,對程序的開發提供更好的支持。

  4) 框架本身,支持為特定程序架構定制組件,程序設計將有更多可能。如根據框架提供的接口,用戶可以自定義HanderAdapter、ViewResolver等組件,以此為Controller、View的變化提供支持。

5、 MVC的衍生------MVP模式

  技術分享圖片

  MVC有效的降低了界面顯示層與業務邏輯層的耦合性,準確的說是web端的MVC模式,對於桌面端來說,MVC實現起來有點復雜,View同時依賴Controller和Model,特別是View-Model用觀察者模式實現了。MVP由MVC演變而來,但還是有很大區別:

  1) view更新方式不同。MVC中是通過策咯模式,由Model調用View的接口刷新,因此View就要依賴Model。MVP中View只依賴Presenter,由Presenter調用View的接口刷新。

  2) MVC的Model是數據模型,只是簡單的數據封裝。而MVP中的Model是業務模型。此Model非彼Model,這點是最讓人迷糊的了,但要分清,所以上圖用Model(service)。

6、 MVC的衍生------MVVM模式

  技術分享圖片

  

  MVVP同樣由MVC演化而來,MVVM與MVP有點類似,不過View的刷新是通過“數據綁定”。很典型的一種實現:前端js框架VUE:

    技術分享圖片

  1) 通過事件驅動,把顯示層大的用戶操作傳遞到js邏輯層

  2) js執行邏輯處理後,修改data域

  3) data域和顯示層html是綁定了的,所以自動把結果刷新到顯示層html

7、 總結

  不論桌面端還是web端,一次程序交互可以抽象為:

    技術分享圖片

    

  1)請求:桌面端通過事件監聽提交;web前端通過事件驅動提交給js邏輯層;後端通過http、https、web service等協議接受。

  2)處理:控制器調用接口處理業務邏輯,以及整個操作流程的統籌控制。

  3)響應:響應內容包括頁面和數據,有可能只有頁面如靜態網頁,也有可能只有數據如json。

  各種模式主要區別從上面第3步總結——響應:

  桌面端MVC,是用觀察者模式實現,由Model調用View的接口刷新界面。

   web端MVC,是通過web容器、SpringMVC等三方庫的支持,將Modle渲染到View再返回給用戶顯示。

  MVP模式,多用於桌面端或安卓等開發,由Presenter調用View的接口刷新界面。

   MVVM模式,多用於web前端開發,通過數據綁定刷新頁面數據。

MVC的發展與應用總結