论坛首页 Java企业应用论坛

代码擂台,特别有请buaawhl

浏览 71362 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-07-17  
我一直有个疑问,为什么一定要钻牛角尖地要把显示逻辑完全从视图层里去掉呢?
视图层留下少量的显示逻辑真的会有很大的坏处吗?当然业务逻辑是不应该在视图层出现的。
这是一个没入门的新手的疑问,希望各位能够解释一下
0 请登录后投票
   发表时间:2004-07-17  
MVC的概念已经深入人心,是经常被大家经常提到的法宝利器。
我感到有必要澄清MVC的概念和来龙去脉,以便大家有一个共识,有一个共同讨论的基础,以便能够把讨论更深入地进行下去,解决真正的问题,而不是在一些技术概念上绕圈子。

一般来说,我不喜欢在名词概念上做文章,发表看法和评论。因为有更多的真正有挑战性的问题需要解决。但通过这段时间的讨论,我感到一种这样的危险:
我们程序员是否过于迷信MVC之类的名词概念,是否可能因此而减弱了或丧失了独立思考的能力?
所以我甘冒天下之大不韪,直言不讳了。:-)

先举一个例子。
很多程序员言必讲,“和页面显示相关的逻辑,只应该存在于View里面,而不应该存在于任何其它部分的代码里面。”
但很少有人真正思考,这个概念从何而来。大家隐约地觉得这个概念来自于MVC。但为什么会有这个概念?这个概念的真实来源是什么?
其实,MVC中关于View的原意是这么说的,“View里面只应该存在和显示有关的逻辑,而不应该存在任何其它的逻辑——比如访问数据库,调用业务逻辑之类”。
纠其源头,这是针对很多程序员在JSP中调用JDBC的现象。

大家仔细比较一下这两句话的区别。可以看出对一个概念的执著和崇拜能够达到怎样的一种潜移默化的思维效果。
本意是为了降低View的作用,只让View做这一件事情,不让View做越权的事情。结果成为:只有View才能做这件事情,其它部分没有权利做这件事情。

那么我们来看,所有的MVC框架中,View部分做到了“只和显示逻辑相关” 吗?View能够脱离数据部分单独存在吗?不管是用JSP,Velocity,还是用TagLib,View都必须知道自己所使用的Object的数据结构,必须访问这些Object的各种属性,才能把它们显示出来。这个View和Model分开了吗?能分开吗?
从概念来讲,MVC是一个完备的概念吗?能够自圆其说吗?

Struts是最流行的Web框架,也正是Struts令MVC概念风靡世界,成为Web程序员的圣经。
下面,我们来确认一下什么是MVC和MVC的来龙去脉。
MVC要求,Model把数据填充到request.attribute里面,通过Controller转发,View再把这些数据从request.attribute里面拽出来显示。
为什么需要这个过程呢?不知道大家想过这个问题吗?更深一步,有没有想过为什么Servlet规范需要request.attribute这个定义呢?

因为你没有别的方式把数据从Model传到View里面去。
MVC是为了解决JSP的天生缺陷而创造的。因为JSP是Servlet。你必须请求Web Server帮你定位并调用JSP/Servlet。既然如此,如何在Servlet之间传输数据?只能通过request.attribute。

Velocity本来和MVC毫无关系,你完全可以在Action里面直接定位调用Velocity Template。
但为了支持MVC,Velocity不得已做了妥协,做了Velocity-tools,来支持MVC。我在前面的贴子里面讲过了。

fastm不具有JSP + TagLib的缺陷,没有需要MVC结构的根本需求。
我只把MVC看作一种可供参考的架构,从来不认为MVC是圣经。既然fastm本身就是离经叛道的。

下面我们探究一下,fastm的Data和View分离做的更好?还是MVC的Data和View分离做的更好?

MVC的View需要了解处理各种类型的Data Object。MVC的View需要知道它们的属性名,甚至需要知道这些Data Object的属性代表什么意义,根据这些属性的值,决定怎样的显示方式(比如,赤字,还是蓝字)。这不是业务逻辑是什么?

fastm的View(我是指Template DOM)只需要处理一种类型的Data Object – ValueSet DOM。ValueSet DOM本身就是数据和模板之间的桥梁,ValueSet DOM同时存放了数据之间的层次关系和数据本身,这正是DOM结构的精华所在。

另外,还有一个情况就是,似乎很少有人认识到DOM概念的重要性,大部分人都执著于Page Scripting技术(JSP,Velocity)。

另一个很古怪的现象就是,TagLib和Page Compent的概念,天生就是和Page Scripting技术(JSP,Velocity)技术 是对立的思路,却共存在View中,也从来没有人质疑。大家都把这当作一种经典思路,努力消化接受了,还研究颇深。其实这不过是 技术自身“修修补补”的结果而已。
0 请登录后投票
   发表时间:2004-07-17  
Xiaohanne 写道
我一直有个疑问,为什么一定要钻牛角尖地要把显示逻辑完全从视图层里去掉呢?
视图层留下少量的显示逻辑真的会有很大的坏处吗?当然业务逻辑是不应该在视图层出现的。
这是一个没入门的新手的疑问,希望各位能够解释一下


其实,这个问题应该反着问。

为什么一定要钻牛角尖地要把显示逻辑加到视图层里去呢?
视图层没有任何显示逻辑真的会有很大的坏处吗?

这都是思维习惯的问题。
Page Scripting 这种东西原来并不存在。
发明了之后,大家习以为常。
却从来不去问,Page Scripting 这种东西为什么要存在?为了解决怎样的问题?
没有Page Scripting就达不到目的吗?

其实,我们应该关注真正的问题本身 -- 动态生成页面内容。
Page Scripting在这方面走的太远了,太复杂了,甚至走入了歧途。
该是技术返朴归真,解决真正问题的时候了。
0 请登录后投票
   发表时间:2004-07-17  
汗,buaawhl说得好深奥,看的我晕晕忽忽的
0 请登录后投票
   发表时间:2004-07-17  
Xiaohanne 写道
汗,buaawhl说得好深奥,看的我晕晕忽忽的


sorry. 我创造fastm的本来目的就是为了把问题简化。
没想到自己在 描述上了犯了 复杂化 的错误。

我简化一下说法。

你是否曾经思考过,为什么我们需要在HTML中加入逻辑代码?
不这样做不行吗?别的方法就达不到目的吗?

在HTML中加入逻辑代码,有什么明显的好处吗?
别的方法不需要在HTML中加入逻辑代码,难道就是一个很大的缺点吗?

这种根深蒂固的思维定势是什么时候建立的?
0 请登录后投票
   发表时间:2004-07-17  
有点明白了,但又不是很明白。
还是来点实例好了,不管庄兄那个高难度例子,给我这样的新手来个简单的:我要显示一个成绩单表的所有记录,那么jsp看起来会这样:
<table>
<tr><td>姓名</td><td>成绩</td></tr>
<c:forEach begin="0" end="${length}" var="i">
<tr><td>${name[i]}</td><td>${score[i]}</td></tr>
</c:forEach>
</table>
这里的逻辑只有一个forEach,我需要在加入它的原因是我不知道会有多少个<tr>要显示。
不知道应该用什么手段才能把“显示length个<tr>”的逻辑从视图层踢出去呢?因为我觉得显示本来就是视图应该要做的事情啊
0 请登录后投票
   发表时间:2004-07-17  
Xiaohanne 写道
有点明白了,但又不是很明白。
还是来点实例好了,不管庄兄那个高难度例子,给我这样的新手来个简单的:我要显示一个成绩单表的所有记录,那么jsp看起来会这样:
<table>
<tr><td>姓名</td><td>成绩</td></tr>
<c:forEach begin="0" end="${length}" var="i">
<tr><td>${name[i]}</td><td>${score[i]}</td></tr>
</c:forEach>
</table>
这里的逻辑只有一个forEach,我需要在加入它的原因是我不知道会有多少个<tr>要显示。
不知道应该用什么手段才能把“显示length个<tr>”的逻辑从视图层踢出去呢?因为我觉得显示本来就是视图应该要做的事情啊


“因为我觉得显示本来就是视图应该要做的事情啊”
视图,你是指View吧?视图,这个概念是从哪里来的?
Servlet规范本身有这个概念吗?
显示方面,Servlet规范只有response这一个概念。
视图View 是 JSP, MVC的概念。

fastm的目标就是替代JSP,当然走的是不同的思路。
fastm概念体系里面,没有明显的View概念,只需要考虑 Servlet Response+ DOM就足够了。

“不知道应该用什么手段才能把“显示length个<tr>”的逻辑从视图层踢出去呢?”
:-) 看来你没有仔细看前面的代码例子。你可以参考一下我和ziyi前面写的fastm例子代码。

不过,这里我还是给出对于你的例子的解答。

fastm template.

<table>
<tr><td>姓名</td><td>成绩</td></tr>
<!-- BEGIN DYNAMIC: tr -->
<tr><td>{name}</td><td>{score}</td></tr>
<!-- END DYNAMIC: tr -->
</table>

你看这个fastm模板中有任何逻辑吗?就是纯粹的HTML。所见即所得。
我还可以给出一个更友好的“所见即所得”的fastm模板。里面加入了一些sample data.

<table>
<tr><td>姓名</td><td>成绩</td></tr>
<!-- BEGIN IGNORED: sample -->
<tr><td>Wang</td><td>90</td></tr>
<tr><td>Zhang</td><td>90</td></tr>
<tr><td>Li</td><td>95</td></tr>
<tr><td>Wang</td><td>90</td></tr>
<!-- END IGNORED: sample -->

<!-- BEGIN DYNAMIC: tr -->
<tr><td>{name}</td><td>{score}</td></tr>
<!-- END DYNAMIC: tr -->
</table>

由于你没有给出 获得name和score两个list的代码。
我这里也就省略了ValueSet DOM部分的代码。
免得引起一些“看上去”的误会,认为fastm需要的代码比JSP或Velocity长。
0 请登录后投票
   发表时间:2004-07-17  
呵呵,了解了,多谢buaawhl
我水平很菜,见笑了,我得到那两个List的方法很乱,就不拿出来献丑了。
平时工作之余也想到过这种“留下示例代码却不执行”的方法,使得在DW中能够直接看到,本来想用taglib实现的,不过没时间做,这么看来我和高手的思路还是走到一块儿去了(自己臭屁一下)。
这样我对您的fastm有一个基本的概念了,有时间我会更深一步去了解以下的,谢谢指教,希望您的fastm越来越好。
0 请登录后投票
   发表时间:2004-07-17  
我来给一个日期格式化的问题。
看看在MVC中,日期格式化的代码(显示相关)应该写在View里,还是写在后台。

format.html

<html>
<body>
<form action="format.do">
choose date format:
<select name="format">
    <option/>
    <option value="month">Month Format</option>    
    <option value="day">Day Format</option>    
    <option value="time">Full Time Format</option>    
</select>
<input type="submit"/>
</form>
<br/>
Date shows here: {date}
</body>
</html>


这个HTML用来提交用户的日期格式选项。
下面是我的fastm的ValueSet DOM代码。

    public static IValueSet makeValueSet(String format);{
        IValueSet valueSet = new ValueSet();; // the whole document

        Date now = new Date();;
        
        String str = "";

        if("month".equals(format););{
            str = monthFormat.format(now);;
        }else if("day".equals(format););{
            str = dayFormat.format(now);;
        }else if("time".equals(format););{
            str = timeFormat.format(now);;
        }
 
        valueSet.setVariable("{date}", str);;
        return valueSet;
    }


整个源代码和可以运行的例子,都在这个贴子附件里。
下载之后,解压,在tomcat中直接运行。

感兴趣的朋友,请用Velocity或JSP写这个例子。
看看在MVC中,日期格式化的代码(显示相关)应该写在View里,还是写在后台。
0 请登录后投票
   发表时间:2004-07-17  
最好能够有运行例子的代码。
如果觉得Velocity, taglib, struts, tapestry的jar太大。
可以不包括这些jar。只要说明需要哪些jar。我们知道如何下载。

另外,把关键的代码列在贴子里,也是一种直观,便于讨论比较的方式。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics