`
fantasy
  • 浏览: 517301 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

我是如何写Service的

    博客分类:
  • Java
阅读更多

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

 

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

 

1:使用断言控制输入。

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

如:

import org.springframework.util.Assert;
private boolean addAttachment(Attachment att) {
  Assert.notNull(att, "att对象不能为空");
}

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

 

2:只抛出RumtimeException

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

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

 

3:在Service层做事务处理

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

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

new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {   
            protected void doInTransactionWithoutResult(TransactionStatus status) {   
                //调用DAO按照ID删除部门   
            }   
});   

 

 

4:Service接口的异常处理

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

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

/**
 * 错误代码定义
 *
 * @author fangtengfei
 * @date   2010-3-3
 */
public enum ErrorCode {
	/**
	 * 用户不能重复
	 */
	User_Not_Repeat,
	/**
	 * 用户名太长
	 */
	User_Name_Too_Long
}
在Service里抛出:throw new FriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());

  

 

5:必须记录日志

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

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

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

 

 6:写有效的注释

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

/**
* 批量添加文档的附件 
* 
* @param att 附件对象,附件名长度为20,附件大小为10M
* @throws FriendlyCodeRuntimeException
 */
private void addAttachment(Attachment... attachment)

 

 

 

 

分享到:
评论
12 楼 fantasy 2010-03-03  
yuanyi_wang 写道
4年就告别研发啊??

因为工作原因,转到产品部了。
11 楼 yuanyi_wang 2010-03-03  
4年就告别研发啊??
10 楼 love1907 2010-03-03  
的确是过来人写的,我现在理解和你差不多,就是对于手动事物这一块,没有这样做过.的确是干事实走过来的人..
9 楼 YiSingQ 2010-03-03  

按照系统的设计来说,事务控制放在业务层,当前Spring框架的事务在开发过程中,大部分人都是采用@Transactional注解或者是<tx:advice/>集合AOP的方式,能够提高开发效率。

LZ其实你应该总结出更多设计经验。
8 楼 lfrick 2010-03-03  
赞同老抛的做法。
我的作法是统一叫Mgr,Dao叫BaseMgr,Service继承BaseMgr叫xxMgr
7 楼 rain2005 2010-03-03  
spring的自动代理事务不是很好嘛
6 楼 fantasy 2010-03-03  
抛出异常的爱 写道
fantasy 写道
抛出异常的爱 写道
用回调来管理事务....
逻辑一多....
几乎想死.

呵呵 我有时候也遇到过这种问题,事务中包含的业务逻辑都会很多,而且参数都必须定义为final的,不知道您有什么好的解决办法?

没好办法
以测试困难为由...
建议大家改用DAO来作了.
而且runtimeException容易忘记对业务错误进行处理.....
就是打有关业务的日志...


在DAO里做,会不会出现事务嵌套?或者说有的方法无法做事务处理,我就出现过这种情况。
5 楼 抛出异常的爱 2010-03-03  
fantasy 写道
抛出异常的爱 写道
用回调来管理事务....
逻辑一多....
几乎想死.

呵呵 我有时候也遇到过这种问题,事务中包含的业务逻辑都会很多,而且参数都必须定义为final的,不知道您有什么好的解决办法?

没好办法
以测试困难为由...
建议大家改用DAO来作了.
而且runtimeException容易忘记对业务错误进行处理.....
就是打有关业务的日志...

4 楼 fantasy 2010-03-03  
抛出异常的爱 写道
用回调来管理事务....
逻辑一多....
几乎想死.

呵呵 我有时候也遇到过这种问题,事务中包含的业务逻辑都会很多,而且参数都必须定义为final的,不知道您有什么好的解决办法?
3 楼 抛出异常的爱 2010-03-03  
用回调来管理事务....
逻辑一多....
几乎想死.
2 楼 fantasy 2010-03-03  
主要是总结一些有价值的经验,写太多大家看得也烦 呵呵
1 楼 yangsheng 2010-03-03  
看的lz对service层理解比较深刻学习了 就是太少了

相关推荐

    asp.net写的web service例子

    ASP.NET Web Service是一种基于.NET Framework的简单方法,用于构建可跨平台、跨语言通信的Web应用程序。这个例子是为初学者设计的,旨在演示如何创建和使用Web Service,以及如何在ASP.NET环境中调用这些服务。 ...

    Centos7-Systemd-Service自定义编写Service应用服务配置说明整理.docx

    环境文件的路径通常为 `/usr/lib/systemd/system/&lt;service_name&gt;.service.d/environment.conf`。 CentOS 7 的 systemd 服务提供了强大的自定义配置功能,允许用户根据需要定义服务的配置信息。通过编写服务配置文件...

    Service向Activity传值(kotlin)

    在Android应用开发中,Service和Activity是两个非常重要的组件。Service用于在后台执行长时间运行的任务,而Activity则负责用户界面交互。在某些场景下,我们可能需要Service与Activity之间进行数据传递,例如本例中...

    自己写的service及调用

    这里我们关注的是"自己写的service及调用",这个话题涉及到Web服务(Web Service)的概念、Eclipse IDE的使用以及Java编程语言的应用。Web服务允许不同应用程序之间的数据交换,通常基于开放标准如XML、SOAP和WSDL,...

    Service 的基础使用方法

    在Android开发中,Service是四大组件之一,它用于在后台执行长时间运行的操作,不与用户交互。本教程将深入探讨Service的基础使用方法,适合初学者掌握。 首先,我们需要理解Service的基本概念。Service并非一个...

    Python编写Windows Service服务程序

    ### Python编写Windows Service服务程序详解 #### 一、引言 在Windows环境下,有时我们需要创建一个后台服务程序,这类程序可以在系统启动时自动运行,并在后台持续运行而不会占用用户的桌面资源。对于开发者来说...

    文件系统账户权限迁(NETWORK SERVICE)

    在windows文件服务器之间拷贝文件时,由NETWORK SERVICE账户权限控制的文件或文件夹在复制粘帖时会出现账户权限丢失的问题。次工具则是对该账户权限查找并设置相应的文件或文件夹。 W3WP.exe所使用的账户为NETWORK ...

    安卓Service学习小程序

    例如,在一个Activity中,你可以这样写: ```java Intent intent = new Intent(this, MyService.class); startService(intent); ``` 这将启动名为`MyService`的服务。一旦启动,Service会经历其生命周期的...

    Android基础 Service

    在Android系统中,Service是四大组件之一,它与Activity、BroadcastReceiver和ContentProvider共同构成了Android应用的核心架构。Service主要用于在后台执行长时间运行的操作,而无需与用户交互。它不同于线程,...

    Android 双进程守护service

    它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着...反正我是信了,demo在此,欢迎指正,很少写博客,就这样吧~~~~~~~忙去了

    mysql 5.7.x 所需mysqld.service文件

    mysql 5.7.x 所需mysqld.service文件

    service使用及发送通知

    在Android开发中,`Service` 是一个非常关键的组件,它允许应用程序在后台长时间运行操作,即使用户没有与应用交互。`Service` 主要用于执行长时间运行的任务,如播放音乐、处理网络请求或定期同步数据。本教程将...

    Android Service的startService

    在Android应用开发中,`Service` 是一个非常重要的组件,它允许应用程序在后台长时间运行操作,即使用户没有与应用程序交互。本篇文章将深入探讨 `startService()` 方法的使用及其在实际案例中的应用。 ### 一、...

    Andriod启动Service定时向服务发送请求(自己写),并震动

    该工程是花了大半天时间查阅相关资料之后,在找到一个老外的demo基础上修改的,...包中并没有写访问服务端部分,这个有点累赘,和我们普通的http请求没有区别. 至于震动,铃声类的,看了下文档,都很简单,象征性的做了一下.

    Android服务Service_详解文档

    在Android应用开发中,`Service`是一个至关重要的组件,它允许开发者在后台执行长时间运行的操作,即使用户已经离开应用程序的界面。本篇文章将深入解析`Service`的工作原理、使用场景、启动方式以及生命周期,帮助...

    QtService 实现Qt后台服务程序

    QtService是一个用于实现windows服务或unix守护进程的开源项目,下载地址 本文使用QtService演示如何实现一个windows下的后台进程,可用于一些简单的windows服务程序中。 博客介绍:...

    一次性生成dao和service层

    只需配合一下vo包名即可生成所有的vo 的dao 和service (当然,您的框架和我不一样只需要改下模板文件即可).本人也是学生,马上毕业了.写完这个以后,我非常深刻的理解这些框架的实现.也非常适合新手学习.附上源文件.

    android service实例

    在Android系统中,Service是一种非常重要的组件,它允许应用程序在后台长时间运行,即使用户与应用程序的界面没有任何交互。本篇文章将深入探讨`Android Service`的实例,帮助开发者更好地理解和运用这一核心功能。 ...

    Action,Service和Dao功能

    在不分层的系统中,我们可以将所有的代码都写到一个地方,比如 Struts 的 Action 类。在这里,我们不仅要处理页面逻辑,还要做业务逻辑,还要做数据访问。为了更好地理解和分离 Action、Service 和 Dao 的功能,我们...

    visual c++ vc编写windows service服务 源程序.zip

    在本文中,我们将深入探讨如何使用Visual C++ (VC++) 编写Windows Service服务,并结合提供的源程序进行分析。Windows Service是一种特殊的后台应用程序,它在没有用户界面的情况下运行,通常用于执行系统级任务,如...

Global site tag (gtag.js) - Google Analytics