多层构架在实践中一些问题

徐牛 发布于 2014/05/13 20:21
阅读 416
收藏 1

最近要开始一个新项目,上一个项目采用贫血的多层构架,感觉IDao,IService大多数都无用,虽然有IDE辅助但是仍然很痛苦,想请教一下大家在实践中是怎么使用多层构架的。

  1. DAO层是否有必要存在?毕竟对于一个电商网站你不太可能将数据序列化到文件吧,而且采用Redis等内存数据库也要特殊处理吧,不会直接替换一个DAO实现了事吧。如果只是作为关系数据库的封装,ORM也已经封装的不错了,Java中的常用的ORM也就Hibernate和ibatis一般根据人员学习成本相比中途也不会无痛切换吧。

  2. Service层什么情况下才需要有不同的实现类?Service不过是作为一些代理和跨dao,entity的调用,直接替换不同DAO实现来更换持久化方案我能理解,但是什么情况下才需要替换Service的具体实现呢?

  3. 开始时接口是否有必要存在?开始就采用接口基本就要两个文件来回跳来跳去,如果开始时候就直接使用实现类直到需要时在引入接口成本是否会很高?毕竟只是声明类型变了,业务逻辑没变。(该问题已有同学回答,参见每一个类都应该有一个接口吗?

引用别人对贫血模型和充血模型的总结(没记错的话应该是javaeye的robbin总结的):

对于Java来说,更加适合采用贫血的模型,Java比较适合于把一个复杂的业务逻辑分离到n个小对象中去,每个小对象描述单一的职责,n个对象 互相协作来表达一个复杂的业务逻辑,这n个对象之间的依赖和协作需要通过外部的容器例如IoC来显式的管理。但对于每个具体的对象来说,他们毫无疑问是贫 血的。

这种贫血的模型好处是:

1、每个贫血对象职责单一,所以模块解藕程度很高,有利于错误的隔离。

2、非常重要的是,这种模型非常适合于软件外包和大规模软件团队的协作。每个编程个体只需要负责单一职责的小对象模块编写,不会互相影响。

贫血模型的坏处是:

1、由于对象状态和行为分离,所以一个完整的业务逻辑的描述不能够在一个类当中完成,而是一组互相协作的类共同完成的。因此可复用的颗粒度比较 小,代码量膨胀的很厉害,最重要的是业务逻辑的描述能力比较差,一个稍微复杂的业务逻辑,就需要太多类和太多代码去表达(针对我们假定的这个简单的工时管 理系统的业务逻辑实现,ruby使用了50行代码,但Java至少要上千行代码)。

2、对象协作依赖于外部容器的组装,因此裸写代码是不可能的了,必须借助于外部的IoC容器。

对于Ruby来说,更加适合充血模型。因为ruby语言的表达能力非常强大,现在用ruby做企业应用的DSL是一个很热门的领域,DSL说白了就是用来描述某个行业业务逻辑的专用语言。

充血模型的好处是:

1、对象自洽程度很高,表达能力很强,因此非常适合于复杂的企业业务逻辑的实现,以及可复用程度比较高。

2、不必依赖外部容器的组装,所以RoR没有IoC的概念。

充血模型的坏处是:

1、对象高度自洽的结果是不利于大规模团队分工协作。一个编程个体至少要完成一个完整业务逻辑的功能。对于单个完整业务逻辑,无法再细分下去了。

2、随着业务逻辑的变动,领域模型可能会处于比较频繁的变动状态中,领域模型不够稳定也会带来web层代码频繁变动。

  1. 为什么Java只适合贫血模型?
  2. 有没有什么场景下可以允许所有业务逻辑和持久化全部揉在Model中。
加载中
1
huan
huan

其实这些问题是仁者见仁,智者见智,不一定有标准答案,下面是我的一下看法:

1 dao层还是有必要存在的。因为dao层是数据访问的最基础的方法,会被service层所复用,肯定需要提取出来,否则会在service层中有大量的重复代码。如果将其提取出来放在service层中会造成service层中既有基础的数据访问方法,又有这些方法的组合,以及业务逻辑混合在一起。太过臃肿。而且service层的方法还是声明式事物的切点所在,将这些方法放在这里容易造成混淆和错误。dao层本身已经非常简单了,mybatis 甚至就是一个接口,连实现类都省了。

2 service层负责业务逻辑的实现,对于普通中小型应用一般来说不会出现需要替换实现类的情况,但是考虑一下生命周期很长较大型的应用,引用外部接口及资源非常多,很有可能需要替换某部分的实现,这个时候写一个新的实现类并修改配置文件就比修改所有相关源码要简单多了。还有一种情况是某些方法是需要暴露给外部系统调用的。这些部分一般需要实现为接口。

3 我认为大多数javaweb应用是不需要接口的。如上所述,在大多数应用中,基本不会变更实现,或者暴露给外部系统使用。

4 java的动态特性不足,或者如引文中所述“表达能力不够强大”,所以不太适合充血模型,会把model类本身以及继承关系弄的异常臃肿复杂。这里可以参考ruby on rails的Active Record 想想如果用java来实现会是什么样子。

5...将所有东西放到model中? 岂不成了一锅浆糊? 

徐牛
徐牛
十分感谢,如果能省略interface的话项目基本就少了一半。感觉就清凉多了。
0
CloudArchitect
CloudArchitect
在实际的项目中 使用大多数开发人员都熟悉的架构比使用优秀高效的架构的可能性大些 如果这个项目很急的话
0
CloudArchitect
CloudArchitect
我不是十分看好粒度小的这种开发模式,因为随着项目的增长 文件过多 反而对开发人员来说是一种灾难
0
leo108
leo108

使用Dao和Service不是为了替换数据库什么的,而是方便修改、重构,各个层之间解耦。

比如数据库的一个表结构不满足需求了,那么通过重构Dao层,就可以对Service层屏蔽修改,即使有接口方面的修改也只需要对Service层做少量修改即可。同理Service内部的实现逻辑发生了变更,对外都是透明的。

徐牛
徐牛
嗯,确实,是我太执着于省略代码了。最烦我的就是类似列出一个用户信息web->service->dao基本上方法都有一句话。感觉太繁琐了。
0
后天雨街
后天雨街

Active Record 想想如果用java来实现会是什么样子

其实这个在java中也有部分的实现过的,比如jfinal之类的,简单明了,很好用。

返回顶部
顶部