随笔-199  评论-203  文章-11  trackbacks-0
在不分层的系统里,我们可以将所有的代码都写到一个地方,比如struts的Action类。在这里,我们不仅要处理页面逻辑,还要做业务逻辑,还要做数据访问。比如说:

  
     public String addUser() {

  if(user == null) {

  return FAIL_NO_USER;

  }

  Result result = null;

  if(Role.ADMIN.equals(user.getRole())) {

  result = doSomethingForAdmin(user) ;

  } else {

  result = doSomethingForOthers(user);

  }

  Transaction trans = sess.beginTransaction();

  Query query = sess.createQuery("update Result set level = :level");

  query.setParameter("level", result.getLevel());

  query.executeUpdate();

  trans.commit();

  sess.close();

  return SUCCESS;

  }


  那么上面的代码,哪些部分是页面的部分,哪些是业务处理,哪些是数据访问呢?我认为,这个划分方法是:Action里只做和页面相关的事,不操作业务对象;Service不依赖于任何表现技术,不操纵任务用于表现的对象,对于业务对象,尤其是跨多个业务对象的操作,要放到Service里面来;最后,单纯的业务对象的存取,组装放到DAO里完成。上面所说的业务对象,就是像上例中role, result等和业务相关的对象,而SUCCESS, inputID等,则是页面相关的部分。因些,可以将上例改为:

  
     public String addUser() {

  if(user == null) {

  return FAIL_NO_USER;

  }

  Result result = service.process(user);

  dao.update(result);

  return SUCCESS;

  }

  在service里:

  public Result process(User user) {

  Result result = null;

  if(Role.ADMIN.equals(user.getRole())) {

  result = doSomethingForAdmin(user) ;

  } else {

  result = doSomethingForOthers(user);

  }

  return result;

  }

  在dao里:

  public void update(Result result) {

  Transaction trans = sess.beginTransaction();

  Query query = sess.createQuery("update Result set level = :level");

  query.setParameter("level", result.getLevel());

  query.executeUpdate();

  trans.commit();

  sess.close();

  }


  这样分层,看起来会显得很麻烦,但事实上确实是大有好处,首先:

  代码更易读。每一层的每个方法的意义和目的更加明确,读以起来受的干扰更少。

  拆开后的每一层都更容易测试。

  具体如何分层,还需要在开发中,多多体会,这没有绝对的界限,也许一开始放在action里的页面的控制后来会上升为业务规则,并被其它地方重用,然后被移入service;也许某一块对数据的存取也变得非常复杂,包含了业务逻辑,然后被移入service;也有可能发现以前写的service根本没有想像的那样的业务逻辑,只是帮助做了一些页面的流程控制,然后被重构成Action的一个方法,等等。

posted on 2009-05-14 18:13 Werther 阅读(5801) 评论(8)  编辑  收藏

评论:
# re: 区分Action, Service 和 Dao功能 2009-05-14 19:39 | too young too simple
too young too simple sometimes native

在实际开发中 这样的分层是对效率的极大浪费  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-14 19:58 | Edward's
@too young too simple
实际开发就是这样吧  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-14 20:49 | stone2083
根据需求来决定的。
系统分层,和公司设立部门的概念是同样的。

一个创业型公司,很可能整个公司就一个人:即是老板,又是程序员,同时还是业务员,等等,
如同一个系统中,一个action做了所有的业务;

一个中型公司,有一个老板,有一个技术人员,有一个业务人员,有一个运营人员,等等,
如同一个系统中,有action层,biz层,service层,dao层等,通过jar包依赖调用;

一个大型公司,有CEO,有技术部们,有业务部门,有运营部门,等等,
如同系统模型中,每个模块存在独立service系统服务,依赖dao api,依赖search engine api,依赖DW api等;
前台又有不同的业务系统,有自己的action,依赖biz层,biz层又依赖独立模块的service api;
系统之间的依赖,采用SOA架构等

不同的企业规模,决定不同的公司组织架构;
不同的产品需求,决定不同的系统架构;



  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-15 09:11 | guest
其实biz层,service层两者可以合并为一层,你们觉得如何  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-15 12:23 | stone2083
一般应用中,biz层和service层的概念就是同一个,硬做分层,是脱了裤子放屁 ,自找麻烦。 :)

当公司规模大了,应用庞大了,复杂了:
比如,当web应用有几十,上百个;task应用几十,上百个。。。
该如何控制和维护业务人员编写的biz和dao呢?

于是乎,就需要抽象出service层(核心组件服务/核心产品服务),service依赖dao api,search engine api,dw api等等,并且通过某些协议,暴露自己的service api

前台应用(web应用,task应用等),通过biz层,调用不同service api(不再涉及dao等底层服务)

如此一来,底层实现发生变化,比如数据库重构等,只要维持service api不变,不会涉及前台应用的变动。

如同上面说的,要不要biz,service,还是根据应用规模来决定的。

  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-16 23:22 | jinfeng_wang
to 楼上:
是不是“脱了裤子放屁”,得取决于你的肠道的功能好不好,不小心有一天,你就会以为是放屁,其实是拉稀。

顺手牵羊式的“脱裤子放屁”,绝对是减少“莫名其妙”问题出现可能性的一个绝佳机会。 在系统演变的越来越复杂的时候,是没有心思和时间再去演变你的原有代码结构的。

如果你的公司,允许你随意改动“既成的可运行”的代码,麻烦你说一下,你公司名字。

  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-05-21 13:25 | stone2083
比喻很形象,也比较能说明问题。站在技术角度上,我非常认同你说的观点。
对于一家长期发展的公司,系统演变会越来越复杂,前期为了贪图方便的设计,总有一天,会带来无穷的痛楚。这些俺都明白。目前也在经历这些痛楚。

但是,确实也存在很多系统,本身业务并不复杂(比如外包公司接手的一次性的小项目),并且也很难看到未来的发展方向(比如针对一些创业型公司的项目),之后重写+数据迁移的方案代价远远小于系统重构的代价,那么我,决不会采用复杂的架构,把简单问题复杂化。
PHP,ROR(使用action+model,没有过多分层)的项目,在中小型项目中,比较流行的,也能说明一些问题。

很多的系统,如果能标标准准按照action->biz->dao的结构写,已经是相当不错了(通过一些应用抛出的错误异常看,很多甚至在jsp上书写大量的业务逻辑,或者在action属性大量的业务逻辑)。要在biz层抽象出biz->service的概念的系统,并不是太多。(至少是中型公司及以上,才需要考虑的)

我说这些,不是为了否决楼上的说辞--其实我是非常认同的观点。
我只是想表明,任何的架构设计,都是需要根据需求以及未来的发展,来决定的。  回复  更多评论
  
# re: 区分Action, Service 和 Dao功能 2009-06-26 17:20 | API
受益良多  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

I'm reading...

Java 60

Head  First SQL

宝贝连接


If you need these books,pls send me emails.
Email:kunpeng.niu@163.com
<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

留言簿(10)

随笔分类(178)

随笔档案(208)

文章档案(1)

新闻档案(6)

相册

1.Java Official Website

2.Java Study Website

3.Java Technic Website

4.Java Video Website

5.Database Website

6.Bookshop Website

7.English Website

8.Friends Link

9.Other Web

积分与排名

  • 积分 - 683783
  • 排名 - 67

最新评论

阅读排行榜

评论排行榜