service, manager and dao


酝酿这篇文章其实有一段时间了,只是最近晚上回家之后没啥动力(颓废?),于是只能在某个休息日的早上写了。

首先说明一下service、manager和dao指的是java web中常见的分层,我要讲的是自己在这种分层设计上的进一步理解,基于从学java开始到现在工作两年左右的经验。

简略地概括下现阶段我对分层的职责的认识:

层次 职责
service 检验输入,控制业务逻辑
manager 主要负责数据库对象到业务对象的转换
dao 数据库调用层

这里面DAO的职责可能毋庸置疑,也很少有人在DAO中加复杂的业务逻辑,部分由于数据库引起的问题可以在DAO层解决。如果业务对象简单的话,理论上可以在DAO层做检验逻辑,但是建议移动到DAO以上便于逻辑复用。
个人认为争议最大的可能是manager。个人以前用过hibernate,hibernate中数据库对象转换、缓存处理都不用太关心,所以可能没有manager层。事实上,个人感觉manager要负责的就是service和dao不负责的东西。常见的就是数据库对象到业务对象的转换,缓存处理等等。
service是最外部的一层。虽然是最外层的,但是不代表可以直接暴露出去。原因主要是分层限制调用只能平层或者调用下层,如果调用了“上层”的话,一方面破坏了分层,另一方面造成职责的混乱。service暴露出去也是一样,很可能存在调用你这个serviceA的另外一个serviceB。如果serviceA暴露出去了,serviceA的职责增加了接受外部请求,但是serviceB没有,导致serviceB变成自己从外部调用自己的服务?可能代码上看起来没啥问题,但是带来的逻辑问题可能会对后期的维护带来很大问题。
service需要关注的第二个的是“前置校验后,后面不需要再校验”的约定,这种约定在分层的基础上减轻了下层的职责。可能很多人听到“防御式编程”,就认为每一层都需要校验,实际上不是这样的。假如分层做得好,只需要第一层做校验就可以了。换句话说,分层的优势就在于职责清晰,特别是在数据校验这种问题上。

以上是个人对于三层的职责的了解,但是具体实现时仅仅了解这些是不够的。很多代码虽然完成了指定的职责但是仍旧逻辑混乱,难以维护。典型表现就是超级长的方法。个人认为这是对于类职责的认识不清晰所导致的。说类职责可能有点学院派的风格,但这实际上是软件开发中需要关注的一项内容,是对后期维护至关重要的一项原则。
我想这时你可能会问,假如manager负责三个职责,比如数据库转换,缓存处理和异步通知,难道要写三个manager?回答是确实要写三个但也不完全是。这里就需要设计模式和编码手段了。比如缓存处理就适合装饰器或者AOP,异步通知适合监听器模式或者AOP,manager的核心逻辑是数据库转换,那就就留着就行了。从个人角度来说,代码虽然是为业务逻辑服务的,但是不代表代码是业务逻辑直接对应出来的,如何在分层、职责、可维护性的前提下匹配两者是一门技巧。换句话说就是微观设计能力。各种设计模式就是前人留给我们最好的微观设计能力的实践,学习了肯定受益。

有点扯远了。总结一下分层的原则是职责,不得“越权”。职责清晰的好处是不用做重复工作(吐槽一句,机器比人更值得信赖)。在分层的基础上分析好类职责,对后期维护非常有帮助。学习设计模式,加强个人的微观设计能力。以上就是个人到现在为止学习到的东西,希望对各位有帮助。


2 responses to “service, manager and dao”

  1. 现在一般公司都有自己的框架,多个项目并行开发下中间层都封装好了,作为具体的action执行者需要关心到的很少

    • 确实有这种情况。不过个人工作中有修改中间层的经历,修改多了,就想写点感想。