MVC的發展與應用總結

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

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

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

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

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

 

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

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

  

  a)       View:負責界面顯示。spring

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

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

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

 

  桌面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數據。可不能夠多線程,可不能夠把功能調用和頁面交互異步處理?那又是否須要同步呢?

 

 

 

三、 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。

 

四、 其餘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的變化提供支持。

 

五、 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)。

 

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

  

  

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

    

 

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

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

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

 

七、 總結

  不論桌面端仍是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前端開發,經過數據綁定刷新頁面數據。

相關文章
相關標籤/搜索