`
runfriends
  • 浏览: 229623 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于用异常控制程序流程的看法

阅读更多

这个问题已经在iteye被讨论过很多了。robbin也发表过看法。现在我觉的有必要总结下。
围绕着这个问题的争论,主要集中在两点;一是效率,一是规范。还有少部分观点认为用异常作程序流程控制有时候会很方便。
以下面的代码为例:

public static boolean isDigit(String src){
    try{
        Integer.parseInt(src);
        return true;
    }catch(Exception e){
        return false;
    }
}

public static boolean isDigit(String src){
    return src.matches("^\\d+$")
}

private static Pattern digitRegex=Pattern.complie("^\\d+$");
public static boolean isDigit(String src){
     return digitRegex.matcher(src).matches();
}

 第一个写法是从别人的帖子里抄过来的,原帖我找不到了。当时作者认为这样写好,因为方便,只有6行代码。

个人觉的这纯粹是一种蛋疼的写法。从效率上说它比第二种写法快,但是恐怕不怎么方便的吧,感觉绕了个大弯。

实际上应该推荐第三种写法,当然占用的内存稍微多一些,但它效率最高。第二种方法写法最简单。

 

Robbin举了另外的例子

try{

   userService.add(user);

}catch(UserExistException e){

   //在此处同名添加用户已存在的处理逻辑

}

 个人认为如果为用户名字段添加了惟一性约束,这么写很好。如果没有惟一性约束恐怕就要这么做了

if(userDao.exist(user)){

   throw new UserExistException(user);

}else{

   userDao.save(user);

}

 在没有惟一性约束的情况下,为什么不这么做?

if(!userDao.exist(user)){
   return userDao.save(user);
}else{
   return USER_EXISTED;
}
public static final int USER_EXISTED=-1;

 不要说为了遵守第三范式什么的,数据量太大的时候,使用字符串做主键和增加太多约束,效率肯定降低。我参与过的所有项目,除了long型主键其它字段一律都不添加任何约束。

 

当然上面那个例子的返回值还可以改成枚举,个人更推荐使用枚举。不过这里只是个例子,本人太懒不想写太多代码。

 

究竟是不是要使用异常作为流程控制条件,恐怕还得依具体情况判断。

 

最后想说的是,不要为了面向对象而面向对象。

定义了太多的业务异常,然后依不同的业务情况去抛出它们,然后在方法的调用处捕获它们。个人一直觉的这是一种蛋疼的做法。

public LoginResult login(String username, String password){
    User user=userDao.find(username);
    if(user==null){
       return LoginResult.USER_NAME_NOT_FOUND;
   }else if(!user.getPassword.equals(password)){
       return LoginResult.INCORRECT_PASSWORD;
   }else{
       return LoginResult.LOGIN_SUCCESS;
   }
}

 如果采用异常恐怕得这么做

public Userlogin(String username, String password){
    User user=userDao.find(username);
    if(user==null){
       throw new UserNotFoundException(username);
   }else if(!user.getPassword.equals(password)){
       throw new IncorrectPasswordException(user,password);
   }else{
       return User;
   }
}
 

为什么不定义一系列枚举,依照不同的业务处理结果返回不同的枚举值?

单看上面的两段代码恐怕没法判断哪个更简单。但是逻辑显然是差不多的。

整个登录流程肯定不会就这么完了,上面只是service层的代码。在action层肯定还要根据service的执行状况做后续处理。

单纯从登录这个操作来看,个人更倾向于第一种做法,到了action层,只需要简单的向浏览器响应枚举值对应的字符串作为结果即可,代码大大减少,而且效率绝对比异常控制要高。

在浏览器端可以根据返回的字符串做后续处理。如果登录流程没有js参与,action也可简单的根据返回的枚举值做后续处理。

 

至少直到目前为止我还没在开发过程中发现非用异常做流程控制不可的理由。

当然hibernate里面用了大量异常作流程控制。如果它不这样做,恐怕就要增加不少数据库访问量,这样在异常方面造成的效率影响没有了,却增加了网络通讯和数据库访问量,显然是得不偿失的。因此,减少数据库访问量、网络数据流量和网络访问次数恐怕是使用异常做程序控制的最大理由。

分享到:
评论

相关推荐

    引言。。过来人对学习Java的看法

    这包括理解基本语法、数据类型、运算符、流程控制语句等。这些是构建任何程序的基础,对于初学者来说,扎实的Java基础能确保你在后续的学习中更加游刃有余。例如,掌握类和对象的概念,这是面向对象编程的核心,理解...

    内部控制审计操作办法.docx

    - 强调了企业层面控制对于其他具体业务流程控制的有效性有着重要影响。 - **三、了解和评价企业层面内部操纵的要紧内容** - **3.1 与操纵环境(即内部环境)相关的操纵** - **3.1.1 治理层的理念和经营风格** - ...

    Java 2编程21天自学通 (第二版)

    3. **控制结构**:学习如何使用if-else、switch、for、while等条件语句和循环语句来控制程序流程。 4. **函数(方法)**:理解函数的概念,学习如何定义和调用函数,以及参数传递的方式(传值与传引用)。 5. **...

    全套审计用底稿.zip

    1. 审计计划与程序:这部分描述了审计的目标、范围以及计划实施的审计程序。审计师会根据公司的业务性质、规模和风险因素来制定审计策略。 2. 风险评估:审计师需要识别和评估公司的财务报告风险,包括内部控制的...

    Dijkstra_Goto

    2. **逻辑复杂度增加**:频繁使用Goto语句会导致程序逻辑变得异常复杂,增加了调试和验证程序正确性的难度。 3. **结构性问题**:Goto语句破坏了程序的结构化特性,不利于模块化设计。这使得程序难以复用和扩展。 ...

    Tenfe:Tenfe应用程序

    5. **异常处理**:使用Java的异常处理机制,确保程序在遇到错误时能够优雅地处理并返回合适的错误信息。 6. **单元测试与集成测试**:可能包含JUnit或其他测试框架的测试用例,确保代码质量和功能的正确性。 7. **...

    内部控制审计操作手册(共154页).docx

    ### 内部控制审计操作手册知识点总结 #### 第一章 获取审计业务约定书 - **获取审计业务约定书**:本部分重点介绍了如何获取审计业务约定书,这是一份正式的书面协议,明确了双方的权利与义务。 - **内部控制审计...

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

     异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获...

    a byte of python

    9. **Control flow**:控制流,讨论条件语句(如if-else)、循环(如for和while)以及异常处理(try-except)等流程控制结构。 10. **Functions**:函数,介绍如何定义和调用函数,以及函数参数和返回值的概念。 11....

    软件测试面试题目(六)

    - 程序流程:首先,输入三个数a, b, c作为三角形的边长。然后检查这三个数是否满足三角形的条件(任意两边之和大于第三边)。如果满足,计算周长并进一步判断三角形类型:等腰三角形、等边三角形或普通三角形。不...

    中国石油大学《管理信息系统》复习题教(学)案答案.doc

    14. 良好的程序设计风格可以明显减少维护和扩充开销,并有助于在新项目中重用已有的程序代码。 15. 面向对象方法是通过特定软件工具直接完成对对象客体的描述到软件结构之间的转化的开发方法。 16. CIO是负责管理...

    democ_DemoC_

    C语言作为一种通用且广泛使用的编程语言,对于硬件控制提供了良好的抽象和灵活性,使得开发者能够高效地编写和调试DMA相关的代码。 DMA的主要功能是在CPU和外部设备之间建立直接的数据通道,减少了CPU的负担,提升...

    优质资料(2021-2022年收藏)审计报告审计期间.doc

    文档标题和描述没有提供具体的信息,但从标签"精品资料(2021-2022年收藏)"我们可以推测这是一份关于审计报告的优质资料集合,涵盖了2021年至2022年的审计知识。以下是根据这部分内容可能涉及的一些审计报告和审计...

    新任生产副总工作计划.doc

    新任生产副总的工作计划主要分为两个阶段,第一周侧重于公司环境、人员和流程的全面了解,第二周则深入生产现场,关注生产过程控制和产品质量管理。以下是对这两个阶段的详细解析: **第一周工作重心:** 1. **...

    hcm培训手册

    - **ATMC调整**: 当需要更换不同型号的机芯时,指出ATMC(自动柜员机控制系统)需要做哪些修改以适应新机芯。 **12.3 使用新版BV的注意事项** - **新版BV**: 使用新版BV时需要特别注意的事项,以确保顺利运行。 **...

    A-Byte-of-Python3(中文版).pdf

    接下来的章节,书中将深入到Python编程的细节,包括基本的数据类型(如整数、浮点数、字符串和布尔值)、列表、元组、字典等数据结构,以及控制流程(如条件语句和循环)。此外,还会介绍函数、模块、异常处理、文件...

    Head First Java, 2nd Edition.pdf

    从基础的变量、数据类型和运算符开始,逐渐引入了Java的流程控制语句(如if语句、循环),然后转向面向对象的概念。书中还着重介绍了Java的异常处理机制,这是编写健壮应用程序不可或缺的一部分。Java的集合框架是...

    Android应用源码某大学学生会通知平台

    11. **异常处理和日志记录**:为了保证程序的稳定性和可维护性,源码会包含错误捕获和日志记录机制,方便开发者排查问题。 12. **版本控制**:开发过程中,源码可能使用Git进行版本控制,便于团队协作和代码回溯。 ...

    信息安全_数据安全_What_Kids_are_Telling_Us_about_t.pdf

    - **持续过度使用设备**:青少年意识到他们很难控制对设备的使用,这可能导致成瘾或持续过度使用,影响学习和生活。 #### 青少年视角下的数字安全好处 - **连接与关系**:青少年通过数字工具能够建立全球性的联系...

Global site tag (gtag.js) - Google Analytics