网址在这里:http://forum.javaeye.com/viewtopic.php?t=627&postdays=0&postorder=asc&start=0
说实在的,这是很理想化的设计方案,真的,我的想法也一样,之所以是这样,主要是因为我看了一本Struts的书,是奥来理出版的,里面就是这样的一个概念,虽然那本书里并没有严格按照这样的思路来做.不过也可以看出这是很完美的,但也是不可取的方案.
不可取的地方在哪里?性能问题,主要是从Service层上来的实体都可进行数据转换(DT),生成View层的DTO,单个实体是一次转换,多个实体,比如set,iterator等,就要n次转化,而这些仅仅是为了使视图层和Service层分离,这是不明智的.
不过这样的模式的出现也是有原因的.因为应用这个Service层可能会有多样的客户端,在适应多种客户端的就要用到这些东西,比如客户端是一个Swing GUI程序?那么他需要的是一个序列化的数据包,而这个数据库仅仅列出的就是健值对,为了设计简单,这个客户端就不应该知道服务器端的类以及类的联系,它仅仅依赖于Service层提攻的DTO,那么就要用到DTO,OK,现在明白robin的设计想法是相当合理,而且重用性很高的.这是大型J2EE程序所常用的方法.
但对于专用于Web而永远不打算有其它客户端的中小Web程序来言,上面的方法已经有些不合时宜了,可以说没有必要死搬了.也就是说设计应该有所退化,至于退化成什么样子,是很让人觉得为难的.我现在的思想是:所有实体对象从最顶层的视图层到最底层的持久层,都是可以共用的,这样就不存在DT的问题,那么中间过程是怎么样的呢?
我的分法是这样:
视图层
-----
控制层
-----
服务接口层
-----
业务逻辑层
-----
持久层
-----
数据库层
穿梭于其中的数据杻带是PO,也可以说它是VO.这些层从上往下依赖,比如说持久层依赖于数据库层,如果数库的设计有所变化,必然会导至持久层设计发生变化,而持久层也因此影响业务逻辑层,从而产生骨牌效应.虽然这样的设计是不好的,但是谁能够解决这样的事情呢?数据库这样最底层最核心的东西都改变了,这必然会影响整个程序的行为,比如说数据库要求多加一个计录评分级别的功能,可是原来的程序里没有这样的功能,而且所有的调用接口都没有写到这方面的功能,那么不就是整个程序只要和这个功能有关的程序文件都要进行修改,这是不可避免的(如果可以避免,请告诉我方法,小弟永生记住您的大恩).
为什么要分多一个服务接口层?很简单,主要是把业务逻辑脱离特定的Web框架,不论是在Struts、Webwork、JSF,他们都可正常运行,当然你也可以不要这一层,把业务逻辑写进Action,这样从而把程序死死绑定到了某个Web Framework,这样的好处是,程序的性能有很小的提高,不过苦果是,某一天要改成其它的Web framework呢?我建议的方案是加多一个服务接口层,这样Action主要的任务就是从接口层取得数据转到视图层去显示,这样Action的重任就很清楚了,它只是一个控制器而已(笑话,那么这些自称MVC的框架,启不只是VC而已?哈…………)
那么什么是业务逻辑层呢?因为程序并不只是涉及数据库操作,而且常会伴随一些文件操作,而这些都是对一实体的一次单元操作,而且是可重用的操作.业务逻辑层就是这样的单元操作接口,他调用持久层,更确切的说是DAO,得到PO,但后进行相关的操作。
注意,这里的持久层不是具体到Hibernate的这些ORM,而只是DAO,具体的ORM由具体的DAO实现。
呵。。。从上面这句话,也许你也会想问一个问题,具体的DAO?对,就是具体的DAO。这里就运用的面向接口编程的思想,层与层之间调用的只是接口而已,每一层都有特定的实现,而这些特定的实现是可插拔的,而且不会影响原程序的运行。你可以用Factory模式生成具体的DAO bean,呵…………这是一个痛苦的过程,而且Factory这样与程序逻辑无关的东西竟然一跃而上进入了我们的代码,这不是一个好的方法,我们可以用一种IoC框架,Spring就是一个极好的东西,注入我们想要的DAO bean,这样我们写代码就可以专心对接口编程了,我们就没有必要担心什么Factory了,呵……
那么实体呢?他能接口化吗?从我现在的所掌握的知识来看,他是不可接口化的,他是数据的载体,也是一些常规操作的载体,也正是因为这样,他是极其重要也是极其简单的,所以,他不用接口化。
好了,终于理清这半年来所思考的东西了,大至上我已经明白怎样去合理的规范化设计一个程序,现在剩下的只是挑选合适的应用框架,然后做第一个Java Web开发。汗,直到现在我都还没有真正开发过Java Web程序呢,呵…………