a) 界面佈局。整個計算器界面要怎麼佈局看起來才合理、美觀。css
b) 業務邏輯。例如用戶點擊「=」按鈕時,根據輸入計算輸出結果。html
c) 界面交互。例如用戶點擊「=「按鈕後,界面有什麼響應,如顯示結果以及結果顯示位置等。前端
無MVC的狀況,如winform在一個Form中,即有計算器的界面顯示代碼,也有觸發監聽器後的流程控制邏輯,還有功能邏輯計算代碼,這三者攪合在一塊兒,程序複雜了後,代碼長度驚人,修改、擴展、閱讀他人代碼都是問題。java
符合「低耦合,高內聚「的軟件工程理念。表如今哪裏?在於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數據。可不能夠多線程,可不能夠把功能調用和頁面交互異步處理?那又是否須要同步呢? |
後來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。
上面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有效的下降了界面顯示層與業務邏輯層的耦合性,準確的說是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)。
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前端開發,經過數據綁定刷新頁面數據。