文章转载自:http://kiral.javaeye.com/blog/606348?page=2#comments 原文还包括精彩的讨论。

马上要告别研发了,所以写一些自己积累的经验,用来纪念4年的似水流年,本篇为第一张,用来介绍自己是如何写Service的,当然我总结的不一定合理,大家一起讨论下。

笔者认为,Service及服务层,服务可以分为功能服务和业务服务,功能服务不易改变,业务服务易改变。所以功能服务添加得多,修改的少,那么我们可以考虑不使用接口。而业务服务,修改和更新都很频繁,所以应该提取接口,用不同的实现来屏蔽业务逻辑。

1:使用断言控制输入。

使用断言来判断有效的输入,这样能够避免异常的扩散,迅速定位错误和减少BUG出现的几率。

如:

Java代码

importorg.springframework.util.Assert;

import org.springframework.util.Assert;

Java代码

privatebooleanaddAttachment(Attachment att) {

Assert.notNull(att,"att对象不能为空");

}

private boolean addAttachment(Attachment att) {

Assert.notNull(att, "att对象不能为空");

}

要学会灵活运用断言,不仅仅是用来断言来判断方法的输入参数是否正确,还可以判断业务逻辑,每次方法调用的输入输出,至于何时使用需要自己根据方法自我判断。

2:只抛出RumtimeException

作为service层,自己不清楚调用方到底是谁,也不知道调用方如何使用自己的接口,那么自己写出的接口最好是抛出RumtimeException,这样调用方能够处理这个异常或者觉得处理这个异常有必要的话,就进行处理。如果使用Exception就得强制那些处理不了的调用方继续向外抛出。抛出RumtimeException的时候需要在注释里申明我抛出了该异常。

Java代码

thrownewRuntimeException("工作流初始化失败!");

throw new RuntimeException("工作流初始化失败!");

3:在Service层做事务处理

大家都知道Service层一般是用来组合DAO,所以经常出现需要事务处理的地方,笔者建议尽量在service层做事务处理。

因为一般业务逻辑都屏蔽在service层。笔者习惯使用Spring的手动事务。

Java代码

newTransactionTemplate(transactionManager).execute(newTransactionCallbackWithoutResult() {

protectedvoiddoInTransactionWithoutResult(TransactionStatus status) {

//调用DAO按照ID删除部门

}

});

new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {

protected void doInTransactionWithoutResult(TransactionStatus status) {

//调用DAO按照ID删除部门

}

});

4:Service接口的异常处理

对于程序异常,service能够处理的自己处理(将异常封装成自己的异常,再向外抛出也算一种处理),不能处理的继续向外抛出。

对于业务异常,以前开发的时候都会向外抛出一个用户友好的运行时异常,这种异常信息是能够直接展现给用户的,如“您添加的用户名已经存在!”,但是现在考虑到国际化,所以觉得Service的接口应该抛出错误代码,定义一个友好错误代码运行时异常,在程序出现条件错误的时候抛出错误代码。错误代码可以定义一个枚举类来实现。

Java代码

/**

* 错误代码定义

*

* @author fangtengfei

* @date   2010-3-3

*/

publicenumErrorCode {

/**

* 用户不能重复

*/

User_Not_Repeat,

/**

* 用户名太长

*/

User_Name_Too_Long

}

/**

* 错误代码定义

*

* @author fangtengfei

* @date 2010-3-3

*/

public enum ErrorCode {

/**

* 用户不能重复

*/

User_Not_Repeat,

/**

* 用户名太长

*/

User_Name_Too_Long

}

Java代码

在Service里抛出:thrownewFriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());

在Service里抛出:throw new FriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());

5:必须记录日志

大家都知道,记录日志的目的,主要是当程序运行在不同的环境下,使用日志来监控程序的运行,有些异常可能会特定的环境发生,而这种环境不容易被重现,所以此时唯一能定位问题的途径就只有日志。

Service层会被各种调用方使用,特别是对外提供Service,环境更会前差万别,如何迅速并有效的定位错误变得尤其重要,所以必须记录有效的日志。

Java代码

logger.error("更新文档出现出错", e);

logger.error("更新文档出现出错", e);

6:写有效的注释

之所以说写有效的注释,是因为有时候,有些方法真的不需要写注释,如addUser,就不要在写注释“添加用户”这样的注释。关键是写有效的注释,注释的作用在于,调用方只看注释而不看代码就能知道如何使用接口,注释应该包括:输入参数的注释,输出参数的注释和异常的注释。特别是List,Sting[]这样的参数要严格说明,笔者认为Service作为一个核心层,注释必须非常详细。另外直观的方法名也能起到注释的作用。

Java代码

/**

* 批量添加文档的附件

*

* @param att 附件对象,附件名长度为20,附件大小为10M

* @throws FriendlyCodeRuntimeException

*/

privatevoidaddAttachment(Attachment... attachment)

java service层怎么写_我是如何写Service的相关推荐

  1. python爬虫实验报告怎么写_[Python]新手写爬虫全过程(转)

    今天早上起来,第一件事情就是理一理今天该做的事情,瞬间get到任务,写一个只用python字符串内建函数的爬虫,定义为v1.0,开发中的版本号定义为v0.x.数据存放?这个是一个练手的玩具,就写在tx ...

  2. 中service层的作用_浅析Java中dto、dao、service、controller的四层结构

    目前我所在的项目组采用的是SpringBoot框架,前端使用BootStrap+jQuery. SpringBoot是BS开发框架之一,不用单独开启tomcat服务器,目前比较流行,一般开发大型项目时 ...

  3. java校验参数防止攻击_程序员写接口参数校验,总是太多if else?一招让你避免体力活...

    对于写Java的程序员来说,不管是写单纯的接口.还是页面后台一把梭,后端参数校验的功能都是整个代码不可或缺的一部分,它可以从系统入口过滤掉一些不合法的数据,以确保我们的系统稳定. 还记得我刚入行Jav ...

  4. uat测试用例怎么写_你会写测试用例吗

    作为一名测试工程师,写测试用例作为一项最最基本的技能谁不会啊!但就是这最基本的技能也会存在很多问题,今天就跟大家分享下写测试用例这件事情上存在的的一些问题和对应的思考: 为什么要写测试用例啊,测试用例 ...

  5. 用java做一个简单记事本_用记事本写一个简单的java程序

    用记事本写一个简单的java程序 第一步: 安装好jdk,并设置好环境变量. 桌面-计算机(右键)-属性-高级系统设置-环境变量-path-在变量值后加上:和jdk安装路径加上(路径即为C:\Prog ...

  6. java 接口是抽象类吗_我是如何理解Java抽象类和接口的

    在面试中我们经常被问到:Java中抽象类和接口的区别是什么?然后,我们就大说一通抽象类可以有方法,接口不能有实际的方法啦;一个类只能继承一个抽象类,却可以继承多个接口啦,balabala一大堆,就好像 ...

  7. 怎么保存java代码怎么写_怎么样能写好Java代码,大神们给点意见?

    怎么样能写好?避免不了多学多练.java代码规范详细版 - 百度文库​wenku.baidu.com 相信很多初学者都跟我抱有一样的想法"代码写出来是给电脑运行的,能运行起来,实现效果就好了 ...

  8. SpringBoot-09:买家订单---Service层的实现_创建订单

    文章目录 一. OrderDTO 二.OrderService 三. OrderServiceImpl中创建订单的实现 1. 查询商品 2. 计算订单总价 3. 订单详情入库 4. 买家订单入库 5. ...

  9. java对象赋值优雅写法_看看人家写的API,那才叫优雅!

    在移动互联网,分布式.微服务盛行的今天,现在项目绝大部分都采用的微服务框架,前后端分离方式,(题外话:前后端的工作职责越来越明确,现在的前端都称之为大前端,技术栈以及生态圈都已经非常成熟:以前后端人员 ...

  10. java 反写_字符串反写(学习)

    今天想起了之前的一个问题,反写字符串的方法. 1. public class shouxie { public static void main(String[] args) { String str ...

最新文章

  1. winform 打印控件
  2. httpclient通过POST来上传文件,而不是通过流的形式,并在服务端进行解析(通过htt......
  3. nagios出现乱码
  4. OpenCV中矩阵的归一化*(Normalize函数)
  5. '0','\0',NULL,EOF的区别
  6. Traefik访问master节点不通的问题定位
  7. 前端使用react-intl-universal进行国际化
  8. 华为又有大动作!继鸿蒙之后,即将发布全新操作系统OpenEuler欧拉
  9. JavaWeb 之 HttpServletResponse
  10. matlab如何调用opencv,matlab调用opencv (mac 或 linux)
  11. VvvebJs可视化前端设计开发工具
  12. 相对标准偏差用计算机,公路工程用计算器计算相对标准偏差(RSD)
  13. 基于 STM32F412RE 的 Flappy bird 游戏机实现
  14. 装自己的服务器(教程)yum-jdk-mysql-防火墙-SVN-redis-申请域名
  15. 【Apache Shiro 身份认证绕过漏洞 (CVE-2022-32532)-漏洞复现实战——关注紫灵小姐姐不踩坑】
  16. 《关于我重装系统后修复VSCode这档事》C++环境配置
  17. 计算机专业在清华学几年,考上清华退学,就为再考清华计算机?
  18. 异构计算的两大派别 为什么需要异构计算?
  19. 微软的100道算法面试题(终结版)
  20. 宝能造车 捏软柿子的野蛮人

热门文章

  1. 微信公众号文章采集思路
  2. 杰理之SRRC认证杂散超标【篇】
  3. WGS84 与 UTM 互转(Python代码版)
  4. 一幅长文细学华为MRS大数据开发(一)——大数据时代的挑战和机遇
  5. 牛客网力扣算法编程之二十一 | 数组 - 明明的随机数 - Java代码实现
  6. 鸿蒙用户突破3亿,拳打谷歌安卓,脚踢苹果iOS
  7. (数据结构)栈(LIFO结构)——概念、进栈、出栈、先进后出的特性
  8. LQR:Linear Quadratic Regulator 线性二次型调节器
  9. 基于压缩传感的脉冲GPR成像技术研究(硕士学位论文初稿20120104)
  10. 2021-12-28学习的道路是寂寞的,学成后的成绩是惊艳的。喜欢热闹是生物的本性,耐得住寂寞方显人性尊贵