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前端开发,经过数据绑定刷新页面数据。

相关文章
相关标签/搜索