我是如何写Service的【转】

原文:  http://www.iteye.com/topic/606348

 

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

 

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

 

1:使用断言控制输入。

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

如:

Java代码 复制代码
  1. import org.springframework.util.Assert;  
import org.springframework.util.Assert;
Java代码 复制代码
  1. private boolean addAttachment(Attachment att) {   
  2.   Assert.notNull(att, "att对象不能为空");   
  3. }  
private boolean addAttachment(Attachment att) {
  Assert.notNull(att, "att对象不能为空");
}

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

 

2:只抛出RumtimeException

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

Java代码 复制代码
  1. throw new RuntimeException("工作流初始化失败!");  
throw new RuntimeException("工作流初始化失败!");

 

3:在Service层做事务处理

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

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

Java代码 复制代码
  1. new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {      
  2.             protected void doInTransactionWithoutResult(TransactionStatus status) {      
  3.                 //调用DAO按照ID删除部门      
  4.             }      
  5. });     
new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {   
            protected void doInTransactionWithoutResult(TransactionStatus status) {   
                //调用DAO按照ID删除部门   
            }   
});   

 

 

4:Service接口的异常处理

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

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

Java代码 复制代码
  1. /**  
  2.  * 错误代码定义  
  3.  *  
  4.  * @author fangtengfei  
  5.  * @date   2010-3-3  
  6.  */  
  7. public enum ErrorCode {   
  8.     /**  
  9.      * 用户不能重复  
  10.      */  
  11.     User_Not_Repeat,   
  12.     /**  
  13.      * 用户名太长  
  14.      */  
  15.     User_Name_Too_Long   
  16. }  
/**
 * 错误代码定义
 *
 * @author fangtengfei
 * @date   2010-3-3
 */
public enum ErrorCode {
	/**
	 * 用户不能重复
	 */
	User_Not_Repeat,
	/**
	 * 用户名太长
	 */
	User_Name_Too_Long
}
Java代码 复制代码
  1. 在Service里抛出:throw new FriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());  
在Service里抛出:throw new FriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());

  

 

5:必须记录日志

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

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

Java代码 复制代码
  1. logger.error("更新文档出现出错", e);  
logger.error("更新文档出现出错", e);

 

 6:写有效的注释

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

Java代码 复制代码
  1. /**  
  2. * 批量添加文档的附件   
  3.  
  4. * @param att 附件对象,附件名长度为20,附件大小为10M  
  5. * @throws FriendlyCodeRuntimeException  
  6.  */  
  7. private void addAttachment(Attachment... attachment)  
/**
* 批量添加文档的附件 
* 
* @param att 附件对象,附件名长度为20,附件大小为10M
* @throws FriendlyCodeRuntimeException
 */
private void addAttachment(Attachment... attachment)

 

 

 

 

 

创建Windows服务程序通常需要使用.NET Framework中的System.ServiceProcess命名空间提供的ServiceBase类作为基础。下面是一个简单的步骤概述和一个基本的C#示例: **步骤**: 1. **添加服务项目**: 使用Visual Studio打开新项目,选择“文件” -> “新建” -> “项目”,然后在“安装/运行时”类别下选择“Windows服务”。 2. **设计服务组件**: 在项目中,会自动生成一个名为`MyService.cs`的服务类,继承自`ServiceBase`。你需要重关键的方法如`OnStart()`, `OnStop()`和可能的其他生命周期方法。 ```csharp using System; using System.ServiceProcess; public partial class MyService : ServiceBase { public MyService() { InitializeComponent(); } protected override void OnStart(string[] args) { // 在这里编启动服务时要执行的任务 Console.WriteLine("Service started"); } protected override void OnStop() { // 在这里编停止服务时要执行的任务 Console.WriteLine("Service stopped"); } } ``` 3. **设置配置**: 右键点击项目,选择“属性”,然后到“应用程序”标签页。设置“服务名”、“帐户”等信息,并确保“自动登录”选项已选中(如果你希望服务在无人值守的情况下运行)。 4. **注册和启动服务**: 编译项目后,右键点击解决方案,选择“发布”。生成的可执行文件会被复制到bin目录下的“publish”文件夹。在控制台里运行`installutil.exe`命令安装服务,例如`installutil.exe MyService.exe`。之后可以使用`sc start`来启动服务。 **注意事项**: - Windows服务运行在系统级别,因此安全性很重要,确保正确设置权限。 - 要调试服务,可以在服务控制台里手动启动它,或者通过代码中的Debug模式来启动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值