`
Mojarra
  • 浏览: 130837 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

白话MVC(一)Model的产生及处理

 
阅读更多

白话MVC(二)

最近在带一“徒弟”,领悟能力很高,对我的能力也提出了新的要求,在“带”的过程中,发现了一有趣的现象,很多东西会用,但是要想用清楚的语言把这些技术描述出来,还是很有难度的。特别是在讲Spring框架的使用,不少知识点的使用已经和学校课本上所教的东西脱节,“徒弟”理解起某些概念起来感到比较陌生。我也不想告诉他,这东西就是这么用的,按照这样的写法去写代码,就能实现模块功能。在我看来,程序代表的是心中的想法,对程序员来说,程序是心中想法的最终实现,有必要对一些概念的产生及作用做进一步的探讨。


在探讨的过程中,发现其实对自己一些概念上的认识也很有提高。好,开头写到这里,遵照无废话的原则,尽力把东西写的言简意赅。希望对初学MVC框架的同学有帮助,希望对深入了解目前主流的WEB上的MVC框架有一个逻辑概念的铺垫。 如果读者发现这里有写的不正确的地方,请直接告诉我,非常欢迎这样的技术交流。


MVC的概念其实最早可以追溯到很久很久以前,并不是WEB开发过程中所首创,但是,MVC也适合WEB上的开发,并真正的在WEB开发领域广泛应用。MVC的第一个字母M是Model,承载着View层和Controller之间的数据传输,是数据传输的载体,通过Model层,解偶了View层和Controller层。 解偶View层和Controller层并不代表View层和Controller层之间没有关系,而是降低复杂度。

 

为了便于理解Model层在开发中所起的作用,先拿一个最简单的用户录入来举个例子。假设要从表单中录入用户时需要填写用户名和年龄,表单提交后,服务器端的Servlet需要拿到表单内填写的内容(这里用ServletRequest来得到数据是为了说明MVC框架中M层所起到的作用),为了得到请求的数据,Servlet的代码大至这样写

 

public class TestServlet  extends HttpServlet
      protected void doPost(ServletRequest request, ServletResponse response) throws IOException {
            User user = new User();
            user.setName(request.getParameter("name"));
            user.setAge(Integer.parseInt(request.getParameter("age").toString()));

            //省略业务处理代码 ... 
            
      }
}
 

分析这几行代码,主要干了四件事情

  1. 创建User对象
  2. 得到Request的参数,
  3. 转换age参数类型,
  4. 调用User对象的setter方法,为User对象赋予相关的值

经过这四个步骤,一个具有业务含义的User对象被创建,作为业务层Bean相关代码的输入条件。从这几行代码里可以看出,Request中的数据转换成具有业务含义的对象,中间经历了四个“必要而繁琐”的步骤。如果程序员天天写这样的代码,岂不是要疯掉?还好,虽然代码只能一行行的写,但是思想却是可以升华的。观察一下这四个步骤,其实每个步骤都不复杂,如果写一段代码能自动创建业务对象,并且自动装配这个对象中各属性的值,那岂不是能省很多时间和精力,让程序员解放出来。

 

想法可以万能,代码不可万能,在要解放程序员的时间与精力之前,对这个业务类User和表单中的参数作一些约定,以便实现自动的装配框架。约定如下:

  1. User类必须有一个不包含任何参数的默认构造函数
  2. User类中的属性名字和表单中的输入控件的名称一样
  3. User类中的各属性必须有默认的getter、setter方法

那框架代码要实现什么功能呢?以这个例子来说,框架要自动的创建User对象,拿到Request中的参数值,转换类型后,赋给User对象相对应的属性。

 

有了上面的三条协定后,再有Java一个非常非常重要的功能--反射,的鼎力相助,上面的自动装配的功能可以得以实现一个比较直观的流程是先扫瞄类中的属性,遍历所有的属性,通过属性名生成setter方法的函数名,通过反射的方法调用这些setter方法,setter方法的参数则通过从Request中得到,并转换成需要的类型,这里的类型转换也是需要通过反射机制来完成(目前这个流程还只能转换java数据中的基本类型,对于复合类型的Bean,为了描述这个流程,暂时不展开论述)。

 

 

现在假设框架已经能自动的装配User对象,编写服务端代码时, 就不再关心如何从Request中取参数了, 只需按照前面的三个约定编写User类。但是事情还没有结束,既然自动装配了User对象,那前面示例的Servlet代码是不是可以变成这样?

 

public class TestServlet  extends HttpServlet
      
      private User user;

      protected void doPost(ServletResponse response) throws IOException {
             
            //省略业务处理代码 ... 
      }
     
      public void setUser(User user) {
            this.user = user;
      }
}

这样的代码看起来却是有些奇怪,为什么doPost方法声明中只有一个ServletResponse参数,而没有ServletRequest参数?因为有框架的自动装配User对象,对于代码的编写者而言,就根本不需要关心ServletRequest这个对象

 

现在进行更大胆的一步假设,且约定所有的Servlet的执行会把Request,Response运送(forward)到一个JSP页面,那么,服务端代码编写时,也不再需要考虑Response对象了,除了前面所说的User类外,再加上一个,这个Servlet的doPost方法执行完后,要把Request,Response运送到那个页面,假如用show_user.jsp这个页面显示被输入的用户信息。这个时候,回头再审视一下刚刚做出的假设,会自然的得出下面的结论,可以编写一个与Request、Response无关的类,只关注User类如何编写,返回一个代表要forward的JSP页面,User对象的装配工作,以及forward本身的这个代码调用都可以交给框架去统一的管理,那真正要编写的服务端代码可以象是这样的

public class TestAction {
      
     private User user;

      public void setUser(User user){
            this.user = user;
      }

      public String execute(ModelVehicle modelVehicle) {
            //业务代码实现
             .... .... ....
            modelVehicle.add("user", user);
            return "show_user.jsp";
      }
}

 

是不是很像Spring MVC的controller类?为了避免和MVC术语中的Controller这个词冲突,仍然叫它Action吧。这个类已经完全和Request,Response无关,当它被框架激活执行的时候,它首选需要框架为它准备好User对象,并且调用setUser方法,赋予TestServlet对象user这个属性,然后execute方法被执行,执行了真正的业务逻辑,同时,把需要在show_user.jsp页面上显示的数据放到ModelVehicle对象中去,TestAction这个对象执行完execute方法后,需要委托框架把ModelVehicle对象中的数据forward到show_user.jsp这个页面上。

注意,这里有两个非常重要的约定,就是Action类必须有

public String execute(ModelVehicle modelVehicle)
 

这个方法的声明,需要显示到页面上的数据,按照约定,须在execute执行过程中放到ModelVehicle对象中去。为了编写的方便,可以继承一个声明了此方法的抽象类。

 

基于这样的服务端代码编写方式,需要框架再提供什么功能呢?这里就引出MVC框架中C需要关注的事情:

  1. 保证一个URI请求优先被框架先拦截,框架能根据这个URI知道哪个Action类会被创建,
  2. Action类的execute方法被执行,需要把ModelVehicle中的数据一并forward到Action类execute方法返回的JSP页面。

因为这里还是重点介绍Model层的事,Controller层的事会在后面继续介绍,其实,Controller是MVC框架中一个枢纽,需要花点篇幅去探讨。


从探讨Model层的过程中,我们发现在Action类中向JSP页面输出数据时,也是采用了Model方式。但是这个Model在处理起来相对简单的多,JSP 2.0规范中的JSTL标签库很容易的将Request中的属性在页面上显示出来,而且还能做一些简单的运算。因此,MVC框架中Model层的主要关注点是如何把请求的数据自动装配成Action所需要的bean,除此外,框架Model层还可以提供复合bean自动装配、输入校验、本地化及国际化、字符集编码转换、多重输出等功能。但是一切的起点是Model层的java bean编写遵照了这三个基本的约定:

  1. 必须有一个不包含任何参数的默认构造函数
  2. 属性名字和表单中的输入控件的名称一样
  3. 各属性必须有默认的getter、setter方法

正是有了这三个约定,让MVC框架Model层实现变得简单,一个好的约定让软件开发变得简单,是不是?

 

[本文系作者原创,如若转载,请注明出处,新浪微博:@仪山湖]

14
11
分享到:
评论
39 楼 yu_duo 2012-11-14  
我慢慢领悟几遍吧。
38 楼 Mojarra 2012-10-09  
欢迎你来讨论真知呀

downpour 写道


非常显然,你已经误入歧途,讨论就此结束。

37 楼 downpour 2012-10-09  
Mojarra 写道
MVC的model层不局限于Struts,因为MVC是逻辑概念上的,struts是MVC的经典实现框架之一。struts是怎么处理Model层的是有探讨的意义,POJO是Model层的一种表现形式,不代表Model层表现形式的全部,比如Model bean包含不包含业务规则?这个问题在贫血模型、充血模型中有论述,不再赘述。
其实,struts中,相对于Model层的处理,C层的处理要简单的多。

Action把model bean传到页面后,你想想,如果没有JSTL、struts签库,在JSP上怎么方便的显示model层的数据?所以,这也属于框架model层处理的事情,MVC的框架Model层的处理是包含了自动装配和页面显示这两大块.

downpour,你想想,是不是这样的?


非常显然,你已经误入歧途,讨论就此结束。
36 楼 Mojarra 2012-10-09  
MVC的model层不局限于Struts,因为MVC是逻辑概念上的,struts是MVC的经典实现框架之一。struts是怎么处理Model层的是有探讨的意义,POJO是Model层的一种表现形式,不代表Model层表现形式的全部,比如Model bean包含不包含业务规则?这个问题在贫血模型、充血模型中有论述,不再赘述。
其实,struts中,相对于Model层的处理,C层的处理要简单的多。

Action把model bean传到页面后,你想想,如果没有JSTL、struts签库,在JSP上怎么方便的显示model层的数据?所以,这也属于框架model层处理的事情,MVC的框架Model层的处理是包含了自动装配和页面显示这两大块.

downpour,你想想,是不是这样的?

downpour 写道
Mojarra 写道
fastupload与struts2的整合马上就会release的,探讨一下struts2框架中Model层的处理,把这个搞清楚,正所谓磨刀不耽误砍柴功呀。

downpour 写道
MVC这种骗人的东西居然还讨论得那么起劲。MVC早已是上个世纪的东西了,搞了10多年,还在讲这些老生常谈的东西。能不能结合实际,把自己真正的想法写出来?不要趋炎附势,实事求是,该是什么就是什么。



问题在于model这种东西,从设计之初就未必是正确的。而你们所有的讨论,都是建立在MVC是经典且正确的前提之下的讨论。这样的讨论我实在是没看出什么价值来,只不过是对之前谁谁谁说的事情换个语气再说一遍而已。

从框架本身的设计而言,实际上早已经颠覆了所谓MVC的概念,是你们硬要把这些框架和这些MVC的概念相互关联起来。比如说,Struts2中的Action,以成员变量的方式接收参数,并以成员变量的方式暴露处理结果,实际上表明Struts2早已不承认什么Model了。这些成员变量本身就是POJO,甚至可以是business object或者persistent object。哪儿还来的什么Model层?SpringMVC倒是真有所谓的Model,但是你们的讨论还真没说明白SpringMVC中的Model的产生形态、作用以及变化规律。

引用
从探讨Model层的过程中,我们发现在Action类中向JSP页面输出数据时,也是采用了Model方式。但是这个Model在处理起来相对简单的多,JSP 2.0规范中的JSTL标签库很容易的将Request中的属性在页面上显示出来,而且还能做一些简单的运算。因此,MVC框架中Model层的主要关注点是如何把请求的数据自动装配成Action所需要的bean,除此外,框架Model层还可以提供复合bean自动装配、输入校验、本地化及国际化、字符集编码转换、多重输出等功能。但


最后这段总结性陈词,慷慨激昂,不过漏洞百出。Action在向JSP页面输出数据时用的是Model嘛?Model在哪儿?在页面显示的时候,全部都是在request里面取的属性并进行计算嘛?把请求数据自动装配成Action所需的bean,到底是Model层的主要职责还是框架的主要职责?按照你的说法,Model不就是那些pojo嘛?哪儿来的自动装配功能?

我觉得这类问题真的可以停止讨论了,因为通常我看到的都只是翻译经典,而没什么真知灼见。楼主的fastupload不错,还是多务实吧。

35 楼 downpour 2012-10-09  
Mojarra 写道
fastupload与struts2的整合马上就会release的,探讨一下struts2框架中Model层的处理,把这个搞清楚,正所谓磨刀不耽误砍柴功呀。

downpour 写道
MVC这种骗人的东西居然还讨论得那么起劲。MVC早已是上个世纪的东西了,搞了10多年,还在讲这些老生常谈的东西。能不能结合实际,把自己真正的想法写出来?不要趋炎附势,实事求是,该是什么就是什么。



问题在于model这种东西,从设计之初就未必是正确的。而你们所有的讨论,都是建立在MVC是经典且正确的前提之下的讨论。这样的讨论我实在是没看出什么价值来,只不过是对之前谁谁谁说的事情换个语气再说一遍而已。

从框架本身的设计而言,实际上早已经颠覆了所谓MVC的概念,是你们硬要把这些框架和这些MVC的概念相互关联起来。比如说,Struts2中的Action,以成员变量的方式接收参数,并以成员变量的方式暴露处理结果,实际上表明Struts2早已不承认什么Model了。这些成员变量本身就是POJO,甚至可以是business object或者persistent object。哪儿还来的什么Model层?SpringMVC倒是真有所谓的Model,但是你们的讨论还真没说明白SpringMVC中的Model的产生形态、作用以及变化规律。

引用
从探讨Model层的过程中,我们发现在Action类中向JSP页面输出数据时,也是采用了Model方式。但是这个Model在处理起来相对简单的多,JSP 2.0规范中的JSTL标签库很容易的将Request中的属性在页面上显示出来,而且还能做一些简单的运算。因此,MVC框架中Model层的主要关注点是如何把请求的数据自动装配成Action所需要的bean,除此外,框架Model层还可以提供复合bean自动装配、输入校验、本地化及国际化、字符集编码转换、多重输出等功能。但


最后这段总结性陈词,慷慨激昂,不过漏洞百出。Action在向JSP页面输出数据时用的是Model嘛?Model在哪儿?在页面显示的时候,全部都是在request里面取的属性并进行计算嘛?把请求数据自动装配成Action所需的bean,到底是Model层的主要职责还是框架的主要职责?按照你的说法,Model不就是那些pojo嘛?哪儿来的自动装配功能?

我觉得这类问题真的可以停止讨论了,因为通常我看到的都只是翻译经典,而没什么真知灼见。楼主的fastupload不错,还是多务实吧。
34 楼 Mojarra 2012-10-09  
fastupload与struts2的整合马上就会release的,探讨一下struts2框架中Model层的处理,把这个搞清楚,正所谓磨刀不耽误砍柴功呀。

downpour 写道
MVC这种骗人的东西居然还讨论得那么起劲。MVC早已是上个世纪的东西了,搞了10多年,还在讲这些老生常谈的东西。能不能结合实际,把自己真正的想法写出来?不要趋炎附势,实事求是,该是什么就是什么。

33 楼 downpour 2012-10-06  
MVC这种骗人的东西居然还讨论得那么起劲。MVC早已是上个世纪的东西了,搞了10多年,还在讲这些老生常谈的东西。能不能结合实际,把自己真正的想法写出来?不要趋炎附势,实事求是,该是什么就是什么。
32 楼 freezingsky 2012-10-03  
dacoolbaby 写道
这里少了一点,就是在execute方法里面。
是如何获取客户端传过来的参数呢?

其实如果你写过最基本的servlet和jSP的话,你就会想着怎么样把传递的数据自动绑定的参数上去。
31 楼 Mojarra 2012-10-01  
写这篇《Model的产生时》出发点是说MVC中model层编写“约定”的,顺便说了一下,基于此约定,MVC框架本身对于Model层自动装配的一个基本实现思路,没想到引起了很大的反响,特别是jinnianshilongnianniva网友,对现行的MVC框架以及面向对象的设计都出了自己的真知灼见,非常感谢二位的参与。

这是白话MVC系列的第一篇,接下来的会说目前两大主流MVC框架struts2,Spring MVC3对于Model层的处理,仍然会聚焦于自动装配,再展开,探讨与自动装配有关的一些点。对于框架本身的实现,我想尽量要讨论的仔细一些,这个讨论会为我的另外一个开源工作计划---- 让strtus2,spring mvc3集成目前最快的表单文件上传文件开源组件fastupload,打下一个良好的基础 ,这个集成工作正好是处于这些框架的Model层之内。



jinnianshilongnian 写道
引用
其实对象设计也不是什么高深理论,只要简单看几本入门书,然后再深入掌握一门设计套路(比如DDD),基本就可以上手了。只是大多数人都不去认真学习基本知识,而是以为用了几个框架,一个万能的模式(MVC)、一个万能架构(三层)就能设计出好的系统了。
话虽如此,现在很多人都是直接学框架 忘记本质,我现在在看《面向对象式软件的构造》,对面向对象又有了一些新的认识。还有吧,框架要学,但要理解框架实现原理,这样才能更好的驾驭,即没事要读好的框架源码。然后配合理论来理解为什么这么设计。
面向对象的好书不多,大部分都是点到为止,没有深入,比如面向对象三大特性很多书都是蜻蜓点水(我真怀疑作者都不明白,都是点到为止 ),《面向对象式软件的构造》这本是面向对象非常好的书。

30 楼 jinnianshilongnian 2012-09-30  
引用
其实对象设计也不是什么高深理论,只要简单看几本入门书,然后再深入掌握一门设计套路(比如DDD),基本就可以上手了。只是大多数人都不去认真学习基本知识,而是以为用了几个框架,一个万能的模式(MVC)、一个万能架构(三层)就能设计出好的系统了。
话虽如此,现在很多人都是直接学框架 忘记本质,我现在在看《面向对象式软件的构造》,对面向对象又有了一些新的认识。还有吧,框架要学,但要理解框架实现原理,这样才能更好的驾驭,即没事要读好的框架源码。然后配合理论来理解为什么这么设计。
面向对象的好书不多,大部分都是点到为止,没有深入,比如面向对象三大特性很多书都是蜻蜓点水(我真怀疑作者都不明白,都是点到为止 ),《面向对象式软件的构造》这本是面向对象非常好的书。
29 楼 jinnianshilongnian 2012-09-30  
引用
当然,如果完全不懂面向对象的设计方法,胡乱的弄一个拙劣的充血模型,那还不如直接写过程代码呢。
其实对象设计也不是什么高深理论,只要简单看几本入门书,然后再深入掌握一门设计套路(比如DDD),基本就可以上手了。只是大多数人都不去认真学习基本知识,而是以为用了几个框架,一个万能的模式(MVC)、一个万能架构(三层)就能设计出好的系统了。
niva 写道
jinnianshilongnian 写道

即使充血也不一定是面向对象,没几位能真正的面向对象,只要用了三层架构其实已经不是面向对象了

当然,如果完全不懂面向对象的设计方法,胡乱的弄一个拙劣的充血模型,那还不如直接写过程代码呢。
其实对象设计也不是什么高深理论,只要简单看几本入门书,然后再深入掌握一门设计套路(比如DDD),基本就可以上手了。只是大多数人都不去认真学习基本知识,而是以为用了几个框架,一个万能的模式(MVC)、一个万能架构(三层)就能设计出好的系统了。


引用

设计模式仅仅是一堆术语,总结了一堆解决编程中问题的代名词,方便大家沟通,就像Java代码一样,但设计模式比代码更加抽象。因此设计模式就是技术术语(你去问学医学的 它肯定不会 不是科普知识),而且是编程领域沟通的一种术语。

引用

模式最大的好处就是方便交流。

我以为,设计模式不仅仅是术语、代名词,而是术语背后的思想,这些思想都是先贤们智慧的结晶(尤其是GOF),这些结晶不是你浏览一遍看个热闹就完事了,而是需要你一遍遍去细读,一遍遍去品味,甚至背诵(至少你要把每个模式的意图部分一字不差的背下来),才能领悟其真谛,进而准确的运用到实际中。
方便交流?有的书上确实这么写,但我至今没有和谁成功的通过模式来达到良好交流的,可能还没达到那个层次吧。。。 其实主要原因是双方对于同一模式的理解都不尽相同。


我以为,设计模式不仅仅是术语、代名词,而是术语背后的思想,  我这句可能不妥  ,设计模式最根本是解决方案,但是就像词典中的单词一样需要有一个名字。这样大家可以用这个名字进行交流。就像你提到的DDD一样。

背诵还是不推荐的,没有意义,不过反复读是有意义的 不同的时间读都会有收获,至今工作三年读GoF设计模式不下20遍 只能说大体了解 不敢说精通。

引用
但我至今没有和谁成功的通过模式来达到良好交流的
其实我们一直在探讨MVC,其实让我说出准确的定义可能说不出,你呢? 我们是不是在交流,而且心中都有自己的MVC,只要我提到MVC,你基本就知道我在说什么?
比如我要设计个产品,当有数据修改,自动通知管理员,能不能想到观察者。
设计模式最终肯定要解决问题的,但有了比如【观察者】这个命名后,我们再讨论时 就不需要解释我们自己心中的方案,如果没有这个名字 我们是不是需要给同事解决半天这个模式意图是什么,怎么定义。
28 楼 niva 2012-09-30  
jinnianshilongnian 写道

即使充血也不一定是面向对象,没几位能真正的面向对象,只要用了三层架构其实已经不是面向对象了

当然,如果完全不懂面向对象的设计方法,胡乱的弄一个拙劣的充血模型,那还不如直接写过程代码呢。
其实对象设计也不是什么高深理论,只要简单看几本入门书,然后再深入掌握一门设计套路(比如DDD),基本就可以上手了。只是大多数人都不去认真学习基本知识,而是以为用了几个框架,一个万能的模式(MVC)、一个万能架构(三层)就能设计出好的系统了。


引用

设计模式仅仅是一堆术语,总结了一堆解决编程中问题的代名词,方便大家沟通,就像Java代码一样,但设计模式比代码更加抽象。因此设计模式就是技术术语(你去问学医学的 它肯定不会 不是科普知识),而且是编程领域沟通的一种术语。

引用

模式最大的好处就是方便交流。

我以为,设计模式不仅仅是术语、代名词,而是术语背后的思想,这些思想都是先贤们智慧的结晶(尤其是GOF),这些结晶不是你浏览一遍看个热闹就完事了,而是需要你一遍遍去细读,一遍遍去品味,甚至背诵(至少你要把每个模式的意图部分一字不差的背下来),才能领悟其真谛,进而准确的运用到实际中。
方便交流?有的书上确实这么写,但我至今没有和谁成功的通过模式来达到良好交流的,可能还没达到那个层次吧。。。 其实主要原因是双方对于同一模式的理解都不尽相同。
27 楼 jinnianshilongnian 2012-09-30  
niva 写道
mvc是解耦模型与展示的一种手段

如果你说的模型只是数据模型而已(失血) 或者只有很少的行为(贫血) 那么你的程序必然是面向过程的

你其实没必要使用mvc这么复杂的模式了 只要有个简单工具将web请求对象或数据库转换成数据模型就可以了 当然你的项目也会和其它过程式的遗留项目一样混乱不堪

不去认真读书或拜师 你以为就凭研究几个框架 胡乱做几个项目 就能理解对象模型的真谛么?


Mojarra 写道
你说的这几本书只是技术方面的,还MVC本身要解决的问题关系不大,本文要探讨的问题是为什么要Model,有了Model,MVC各层需要负责什么样的工作,怎么协调起来的?同样,也用这样方式去探讨MVC中其他各层。

至于实现上采用什么模式,相对于MVC的目标和各层功能来说,处于次要地位。认定目标,“忘记”模式,才能无招胜有招





即使充血也不一定是面向对象,没几位能真正的面向对象,只要用了三层架构其实已经不是面向对象了

引用
你其实没必要使用mvc这么复杂的模式了 只要有个简单工具将web请求对象或数据库转换成数据模型就可以了 当然你的项目也会和其它过程式的遗留项目一样混乱不堪

嗯,比如struts1就使用BeanUtils完成模型数据的组装。

MVC设计思想的核心还是解耦,解耦谁呢? Model-View,不知道这一点我觉得对MVC就是根本不了解,那再问下自己为什么需要解耦Model-View?引入Controller,它都负责那些职责?

引用
引用博主的【你说的这几本书只是技术方面的,还MVC本身要解决的问题关系不大】

设计模式仅仅是一堆术语,总结了一堆解决编程中问题的代名词,方便大家沟通,就像Java代码一样,但设计模式比代码更加抽象。因此设计模式就是技术术语(你去问学医学的 它肯定不会 不是科普知识),而且是编程领域沟通的一种术语。

引用
引用博主的【“忘记”模式,才能无招胜有招】

话说如此,没有模式我们怎么沟通呢? ,其实不是忘记模式,而是不要刻意去背模式,经验到了自然就会了,模式最大的好处就是方便交流。

欢迎探讨
26 楼 niva 2012-09-30  
mvc是解耦模型与展示的一种手段

如果你说的模型只是数据模型而已(失血) 或者只有很少的行为(贫血) 那么你的程序必然是面向过程的

你其实没必要使用mvc这么复杂的模式了 只要有个简单工具将web请求对象或数据库转换成数据模型就可以了 当然你的项目也会和其它过程式的遗留项目一样混乱不堪

不去认真读书或拜师 你以为就凭研究几个框架 胡乱做几个项目 就能理解对象模型的真谛么?


Mojarra 写道
你说的这几本书只是技术方面的,还MVC本身要解决的问题关系不大,本文要探讨的问题是为什么要Model,有了Model,MVC各层需要负责什么样的工作,怎么协调起来的?同样,也用这样方式去探讨MVC中其他各层。

至于实现上采用什么模式,相对于MVC的目标和各层功能来说,处于次要地位。认定目标,“忘记”模式,才能无招胜有招



25 楼 jinnianshilongnian 2012-09-30  
引用
充血、贫血对Model层的用途没有影响

这个必须有影响 架构不同。

其实这里我对贫血模型说的不对 应该是失血模型 

引用
比如,验证User.age属性是否大于65岁,不需要service层的支持,这个验证直接在Model层内完成,也可以采用充血模型。

这是贫血模型。

引用
假如需要验证User.name是否已经存在于数据库,这个则需要service层的支持。这个验证就不能写在Model层内。

这也是贫血模型。

关于涨血模型实现,可以参考下涨血的框架,涨血的一般都是领域驱动开发:
csdn开源的ServiceFramework - 开源的羽量级Java Web服务框架
Naked Objects
这种框架适合做快速开发。

我抛离主题了
24 楼 Mojarra 2012-09-30  
jinnianshilongnian 写道
Model不仅仅封装数据,其实还封装行为的,即充血模型。但我们现在用的Model大部分都是贫血模型,只封装数据,行为转到service层维护


充血、贫血对Model层的用途没有影响,Servcie层是Model需要和外部资源交互,或者需要用到外部服务时才用上,比如,验证User.age属性是否大于65岁,不需要service层的支持,这个验证直接在Model层内完成,也可以采用充血模型。假如需要验证User.name是否已经存在于数据库,这个则需要service层的支持。这个验证就不能写在Model层内。

在Model层内的验证功能,MVC框架可以提供,需要Service介入提供验证的功能,MVC框架不能提供,因为这个已经超出框架本身所关注的范围之外。

View层中,显示数据时是按照约定来实现的,也就是View层不关心Model是充血、失血的

    1,必须有一个不包含任何参数的默认构造函数
    2,属性名字和表单中的输入控件的名称一样
    3,各属性必须有默认的getter、setter方法

第三条的约定中的默认getter方法是给VIEW层准备的。
23 楼 jinnianshilongnian 2012-09-29  
Model不仅仅封装数据,其实还封装行为的,即充血模型。但我们现在用的Model大部分都是贫血模型,只封装数据,行为转到service层维护
22 楼 jinnianshilongnian 2012-09-29  
Mojarra 写道
@jinnianshilongnian
在MVC之前,Model和View是强依赖关系?看来MVC确实是三角关系呀   站在任何一个点上,另外两个点都被解耦了。

Model是结构及用途是由业务决定的,跟如何在VIEW上输出这些数据,如何输出到不同技术的视图,本身就不是Model及controller关心的事情,而是View层份内之事及框架考虑的问题。
jinnianshilongnian 写道

Model和View一直是存在的 ,引入Controller目的是解耦两者的强依赖关系。
好处很明显,比如你看看struts2/springmvc架构就可以体会的到:
1、更换View技术/页面 对Model没有影响;
2、使用不同的Model 对View如何渲染 没有影响;




呵呵,MVC确实有时候让人很迷惑,我也有段迷惑期 感觉自己明白了 其实没明白。

找了一份Model1、Model2架构 sun上边的找不到了
http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html

MVC更多的是职责的分离,没有依赖的应用程序是应用程序嘛,  要有关系必须有依赖。
但重点是M-V之间的关系越弱越好,对了正如spring之父Rod Johnson所说web层要尽可能的薄薄的,在他的《Expert One-on-One J2EE Design and Development》也讲了web层设计思想 非常不错。

M-V强依赖 会造成很难更换视图页面,这是重点,比如今天以表格显示  明天说用图形化、后天给我来个excel,越接近用户变化越快 所以尽量薄 和 轻。

引入C可以解耦他俩 ,负责协调Model/View(分派/选择[策略])。
21 楼 Mojarra 2012-09-29  
@jinnianshilongnian
在MVC之前,Model和View是强依赖关系?看来MVC确实是三角关系呀   站在任何一个点上,另外两个点都被解耦了。

Model是结构及用途是由业务决定的,跟如何在VIEW上输出这些数据,如何输出到不同技术的视图,本身就不是Model及controller关心的事情,而是View层份内之事及框架考虑的问题。
jinnianshilongnian 写道

Model和View一直是存在的 ,引入Controller目的是解耦两者的强依赖关系。
好处很明显,比如你看看struts2/springmvc架构就可以体会的到:
1、更换View技术/页面 对Model没有影响;
2、使用不同的Model 对View如何渲染 没有影响;


20 楼 jinnianshilongnian 2012-09-29  
leyen 写道
还是好好研究研究spring mvc吧,这套东西自己也弄过,回过头来看spring MVC更高明.

像springmvc/struts2其实都是改造过的MVC 不再是纯正血统了,只有struts1还算是纯正血统 可以从它开始,并且能体会标准MVC的一些缺点并知道如何改进的。

相关推荐

Global site tag (gtag.js) - Google Analytics