我的菜菜的个人总结

    
scaupdc
09-07-31 4 392

昨晚思考了一下MVC、DAO、Service、EJB、Spring、Hibernate等一堆东西,也乱想了一堆,准备写成文字理一理乱乱的头脑。 ­本人一小菜鸟,不知道理得对不对准不准,如果有发现问题的一定要告诉我啊!不要让我一错再错,如果有牛人能指导一二那么我更开心了,哈!谢谢!

我个人的DAO的实现一般是根据不同的MODEL对象有不同的DAO接口,而每个DAO接口有不同的实现,因为我觉得一个DOMAIN虽然一般来说只需要一个DAO接口现实类就可以了,但是为了应用的扩展我觉得需要预留实现。而每个DAO接口对应同层次的DAO FACTORY接口,而DAO FACTORY的实现类就负责创建具体的DAO实现类。 ­

然后是Service层咯,先定义Service层即将暴露给Client的接口以及Service方法,­然后编写具体Service实现类,Service实现类一般都会依赖DAO,然后DAO再设置DOMAIN,反馈到DB中去。

  如果在MVC中呢,如果是Struts2,一堆的VIEW层的东西不重要,如HTML、JSP、FREEMAKER,各种标签库,各种Ajax,各种RIA。然后重要的是在ACTION,ACTION夹杂在Interseptor Chain中,可能更前阶段会是Filter或Servlet,不管怎样是来到了ACTION了,ACTION这个控制器根据VIEW层的请求动态决定调用哪个MODEL,相对MODEL来说ACTION是个客户端了。MODEL在MVC里是封装了业务逻辑的,这时候其实也就是同处于服务器端的Service组件来充当MODEL,ACTION将从MODEL反馈的数据再次封装起来Request到新的VIEW中去。嗯,应该是这样的。

  那么是有问题了,就是耦合度问题。很多层面的高耦合问题需要被解决。简单来说就是要让一切new操作消失。如ACTION中调用的MODEL,Service实现类总是依赖具体DAO还有DOMAIN,具体的DAO实现类还依赖显式创建相应的FACTORY实现类,这一切都是耦合的表现,那么如何降低耦合呢?嗯,是时候让Spring来工作了。不管是通过XML配置文件还是Annotation,现在耦合问题算是解决了,需要修改的就是客户端,也就是ACTION,代码量一定会比重构前简单易懂!这样把依赖转移到了ACTION。但毕竟ACTION总是相对少量且稳定的。

  回过来想想DAO和实体持久化的问题。DAO发现这玩意不适用于比较大型复杂的应用,不然的话那要多少海量的FACTORY和实现类!!DAO调着调着就让人上吊了!还是借助容器来自动持久化好点吧,那就Hibernate吧,如果不需要分布式的话。这样DAO算是退化隐形了,其实它还是在的,只是形式不一样了。好吧,不用手动编写CRUD了。工作流程大概就是:编写持久化单元XML配置文件,给DOMAIN加上持久化注解,Client调用Service接口中的方法,利用PersistenceContext注入EntityManager这样Service直接就操纵了DOMAIN,一旦事务提交则也同时完成持久化工作。

  这样的话不需要事先运用DB来手动编写SQL语句创建各种表,甚至连DB类型都不用管,在Hibernate里配置好DB方言,然后当应用首次启动则自动将实体导出为各种DB的各种表,前提是配置好映射关系及主键生成策略。说到这里,突然想起了Jdon里天天提到的DDD,也就是Domain-Driven Design,主张忘记数据库,只关注领域模型,这一点我也同意并喜欢,但是领域模型如何创建是个问题?我更看重的是架构与伸缩性、扩展性等与软件工程有关的要素。我想,这时候设计模式派上用场了。当然,Hibernate等ORM框架不会帮你自动将整个架构的全部都生成表,也不可能这样,更不应该这样。虽然现在各种框架运用设计模式帮开发者省了很多架构方面的思考,但框架从来都不是为特定应用产生的,核心的架构还是需要人来手动设计,这时设计模式也许就很重要了,当然,这其中还需要UML。

  当然上面的情况也许很难适用于遗留应用,那是二次开发,不会有那么先进的开发设计理念。

  如果是分布式呢?这样的话会有所改变。假如是EJB,首先在Service接口方面的方法暴露是很需要慎重考虑的。暴露给远程客户端还是本地客户端是个问题。之前的Service实现类演变成了各种SessionBean,这时又要考虑状态State了,业务的话一般会是Stateless,用户会话的连接上会采用Stateful,之前的DOMAIN现在成了EntityBean,具体采用哪个持久化技术,需要看看应用服务器的支持,或者是标准的JPA,或者是内置的开源框架,如Hibernate。容器提供了一堆服务,服务是采用横切插入的方式来提供的。类似于AOP,其它不说就说事务吧。公布式事务可能会用到了,JTA事务内部跨越了多个SessionBean的多个业务方法,但还好是由容器管理。还有关于数据源datasource,由于是分布式应用,DB的数量没有限制了,相应的datasource也没有数量限制了,应用在不同DB不同DS间自由持久化。

  还有可能需要消息服务JMS吧,它应该也归于Service层吧,只是它的Service是消息生产与消息消费,Message-Drive Bean也许最适合做这类工作。其实这种异步的消息传输很难跟分层结合起来,可能也可以,但自己没经验,也许可以这样:在Service层中独立创建一个Message层,VIEW层利用Ajax异步读取JMS容器里的消息队列,当然,ACTION还是要有的。

  这样,大概的分布式应用应该是这样:一个客户端(远程客户),一个服务器端,客户端通过Service接口暴露的方法作为契约,通过JNDI查找EJB组件,然后返回EJB组件的代理对象,这过程中间由容器生成跟EJB组件具有相同接口的存根,还有服务器端的骨架对象,网络传输的实现以及对象的序列化反序列化对于客户端来说是透明的。代理对象运行业务方法并开启可能存在的容器服务。

  基本就这样。

banq
2009-07-31 16:53

基本对头,是一个JavaEE架构的理解。

不过文中提到如何解决依赖,需要IOC或DI依赖注射模式,Spring只是一个实现产品。

scaupdc
2009-07-31 16:57

哈!很谢谢彭老大(跟我同姓)的指点!或者我下一步应该怎样做?来提高自己

banq
2009-07-31 17:04

需要对领域建模方面多了解,也就是Model。特别是区分Service和Model如何和外界交互。

tomcyndi
2009-08-03 00:06

"当然,Hibernate等ORM框架不会帮你自动将整个架构的全部都生成表,也不可能这样,更不应该这样。"
楼主的这句话是说在Hibernate里不能为模型自动生成表吗?
如果是这个意思的话,那么我觉得楼主错了哦。其实Hibernate可以自动为模型生成对应的表的。
可能我理解错了楼主的意思也不一定,望见谅。