`

关于方法返回值的两种处理模式

    博客分类:
  • Java
阅读更多
目前在处理返回值方面, 有两种代码风格:

一种是这样:
result = method1();
if (result is error){ //根据返回结果判断是否退出
         ...//加错误码
         return result;
}
result = method2();
if (result is error){ //根据返回结果判断是否退出
         ...//加错误码
         return result;
}
do something...


另一种是:
try{
         method1() // 如果有逻辑问题抛出ErrorCodeException

         method2() // 如果有逻辑问题抛出ErrorCodeException

         do something...
}catch(ErrorCodeException e){
         // 将ErrorCodeException异常转换为Result
         return result;
}


但是我推荐采用第二种方式, 理由主要有三个方面:
1. 从重构的角度来说, 如果一个方法中有多个return出口, 当方法膨胀之后需要将一块代码抽取出来单独形成一个方法的时候比较困难, 而采用异常的方式则可以很容易的抽取出单独方法.
2. 从代码重用的角度来说, 第一种如果method1, method2方法有多个地方调用, 这些需要调用的地方大部分情况下都要对结果进行判断加错误码并返回结果, 这个是重复的代码, 这样重复性代码在ic中是随处可见的, 我希望通过抛错误码异常的方式来减少这种重复的东西.
3. 从封装的角度来说, 将非正常结果的处理封装在方法的内部, 可以提高内聚性.

这样做的两个缺点:
1. 必须将method1, method2套在一个try...catch中, 然后将ErrorCodeException转换成result.
2. 还有一些方法的确需要根据情况自己处理返回值的, 不希望抛出异常, 你必须提供一个不抛出异常的方法
3. 在性能上, 因为需要使用到异常堆栈, 这个会有一定的性能损失, 如果是分布式应用的话, 尽量改错误码, 而不是异常, 因为异常比简单的错误码方式序列化的成本会更高

我采用第二种方式是来自于对这样的语句变体: 有些方法在开始处都会对参数进行检查的卫语句, 比如非空, 非0检查, 如果参数不合格抛出IllegalArgumentException(如果不是因为要返回错误码, 完全可以抛出IllegalArgumentException).
分享到:
评论
3 楼 macrochen 2010-07-23  
flysnowxf 写道
我们项目的rest层也使用了第二种方法。但这样catch的代码非常地多,也都是重复的,不知道有什么好的解决方式吗?如果在groovy中,用闭包就可以很优雅地解决了。
		try {
			// 业务处理			
			// 包装结果
			result.setCode(ResultCode.SUCCESS);
		} catch (IllegalArgumentException e) {
			result.setCode(ResultCode.PARAMS_NULL);
		} catch (VersionException e) {
			result.setCode(ResultCode.VERSION_NOT_MATCH);
		} catch (SessionNotExistException e) {
			result.setCode(ResultCode.SESSION_NOT_EXIST);
		} catch (SessionException e) {
			result.setCode(ResultCode.SESSION_EXCEPTION);
		} catch (UserNotExistException e) {
			result.setCode(ResultCode.USER_NOT_EXIST);
		} catch (MessageNotExistException e) {
			result.setCode(ResultCode.MESSAGE_NOT_EXIST);
		} catch (PowerUserException e) {
			result.setCode(ResultCode.POWERUSER_EXCEPTION);
		} catch (Exception e) {
			result.setCode(ResultCode.UNKNOWN);
		}

应该在抛出指定异常(比如PowerUserException)的具体地方直接返回包装了错误码的ErrorCodeException, 然后在最外层捕获ErrorCodeException, 然后转换成result
2 楼 flysnowxf 2010-07-23  
我们项目的rest层也使用了第二种方法。但这样catch的代码非常地多,也都是重复的,不知道有什么好的解决方式吗?如果在groovy中,用闭包就可以很优雅地解决了。
		try {
			// 业务处理			
			// 包装结果
			result.setCode(ResultCode.SUCCESS);
		} catch (IllegalArgumentException e) {
			result.setCode(ResultCode.PARAMS_NULL);
		} catch (VersionException e) {
			result.setCode(ResultCode.VERSION_NOT_MATCH);
		} catch (SessionNotExistException e) {
			result.setCode(ResultCode.SESSION_NOT_EXIST);
		} catch (SessionException e) {
			result.setCode(ResultCode.SESSION_EXCEPTION);
		} catch (UserNotExistException e) {
			result.setCode(ResultCode.USER_NOT_EXIST);
		} catch (MessageNotExistException e) {
			result.setCode(ResultCode.MESSAGE_NOT_EXIST);
		} catch (PowerUserException e) {
			result.setCode(ResultCode.POWERUSER_EXCEPTION);
		} catch (Exception e) {
			result.setCode(ResultCode.UNKNOWN);
		}
1 楼 thebye85 2010-05-13  
 

相关推荐

    Js 弹出框口并返回值的两种常用方法

    1.window.... 弹出框中通过window.returnValue来设置返回值,上面的value拿到的就是这个值,然后主窗口中可以对 这个值进行处理,实现交互处理 注:模式对话框的应用就在于它的返回值,可以返回简单字符窜

    单例模式 工厂模式DEMO

    3、两种比较器以及sort()方法的重载: 结论:Icomparable接口在需要比较的类中实现;Icomparer接口在任何类中实现,使用时只需将这个类的对象作为参数传给Sort()就行。 4、接口的使用 结论:接口作为参数,即接口的...

    从模式讲到设计模式再到面向对象设计模式

    目前最有影响力的书籍是:《设计模式:可复用面向对象软件的基础》,它共编录了23种设计模式,分三大类别:创建型模式、结构型模式、行为模式,其中有一种创建型模式是抽象工厂设计模式。 在学习抽象工厂设计模式...

    uthing SDK for Java 编写于 JDK 1.8.rar

    SDK 简介 提供服务 Authing SDK 提供了授权服务 (OAuthService)、用户服务 (UserService)、用户管理...SDK 提供了同步和异步两种调用方式,适用不同的场景。 若需要等待返回结果处理后面的数据,比较适合同步调用

    嵌入式系统课程设计报告.doc.doc

    我们小组设置了两种模式,切歌模式和音量模式,并定义左键为模式切换键,实现不同 模式的选择和按键的复用。拓展功能: 基本思路是通过定时器中断来产生一定频率的50% 空占比的脉宽调制波,用此脉宽调制波激励扬声...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    下例定义了一个 Point 类 ,并且声明了它的两个变量 x、y 坐标 ,同时实现 init()方法 对 x、y 赋初值 。 class Ponit { int x,y; void init(int ix, int iy){ x=ix; y=iy; } } 类中所定义的变量和方法都是类的...

    C#全能速查宝典

    2.2.3 BeginEdit方法——将单元格置于编辑模式下 153 2.2.4 Button控件——按钮控件 153 2.2.5 CancelEdit属性——取消更改 155 2.2.6 CanPaste方法——是否可以粘贴数据 155 2.2.7 CanRedo属性——是否有可以重新...

    spring-boot-103:满足命令查询责任分离(CQRS)模式实现的两个应用程序

    它是一种设计模式,用于强制将修改应用程序状态的操作与使应用程序状态保持完整的操作分开。 引用:“对象被分为两个对象,一个包含命令,一个包含查询。” :提出问题不应改变答案。 Java术语:如果您有返回值...

    超级有影响力霸气的Java面试题大全文档

     Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常...

    千方百计笔试题大全

    237、触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。 56 238、EJB容器提供的服务 56 239、EJB的角色和三个对象 56 240、EJB的几种类型 56 241、bean 实例的生命周期 56 242、...

    java面试宝典

    237、触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。 56 238、EJB容器提供的服务 56 239、EJB的角色和三个对象 56 240、EJB的几种类型 56 241、bean 实例的生命周期 56 242、...

    java 面试题 总结

    Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常来...

    wildcard:通配符模式匹配

    有两种方法可以使用这个类。 当您只希望将带有通配符('*' 和 '%')的字符串与另一个字符串进行一次比较时,第一个很有用。 让 sWild 是一个通配符字符串,而 sTame 是一个非通配符字符串。 使用方法是: boolean...

    AIC的Java课程1-6章

     理解运用继承和组合两种重用方式定义堆栈和队列,知道两种重用方式的适用场合。  理解使用递归方法构建二叉排序树,前序、中序、后序遍历二叉树。  学习ArrayList与LinkedList类,理解封装数组和...

    DWR.xml配置文件说明书(含源码)

    Creator可以配置类的成员函数的访问权限.creator有授权访问(指明可以被访问的方法)和拒绝访问(指明不允许访问的方法)两种配置方式. 如果要设置除了setWibble方法之外的所有方法都不可访问可以采用下面的设置. ...

    gradleTest:gradleTest

    com.dp设计模式代码里氏替换原则:A中方法1两数相加,B继承A转换方法方法1为相减,转换为A,B都继承基,A中有相加,B中有相减迪米特法则:成员变量,方法参数,方法返回值中的类为直接朋友。出现在局部变量中的类...

    服务虚拟化Terminator.zip

    通常有两种方法: 针对协议的通用桩,可以预先设置请求对应的返回值以及匹配条件,这样系统未开发完之前可以使用这个桩来代替真实的服务; 录制回放方式,在第三方服务可用的时候将链路上的数据录制下来,当不...

    雄迈OCX控件开发包

    (目前只支持0和2两种情况;)(-1使用配置文件提供的设置类型) 返回值:TRUE表示成功,FALSE表示失败。 6.2开始全录像 BOOL StartRecordAllChannel(LPCTSTR lpSaveFile,long nType) 功能说明:对正在预览的所有...

Global site tag (gtag.js) - Google Analytics