关于异常的设计

在我本身搭建的开发框架中有设计这么两种异常,以下:java

1.业务逻揖异常程序员

/**
 * 业务逻揖异常
 * @author lenovo
 * 
 *
 */
public class ServiceException extends Exception {
	public ServiceException(String msg) {
		super(msg);
	}
}

2.非业务逻揖异常(通常是数据异常或系统异常等)
数据库

/**
 * 非业务逻揖异常
 * @author lenovo
 *
 */
public class FaultException extends RuntimeException {

	public FaultException(String msg) {
		super(msg);
	}
}

举个例子,好比登陆的的业务逻揖:app

public class UserService {
    .....
    public User login(String username, String password) throws ServiceException {
        User user = null;
        //根据帐号获取用户对象
        List<User> users = userDao.queryByUsername(usernmae);
        if (!users.isEmpty()) {
            if (users.size() > 1) {
                //根据用户名可查到1个以上的用户,这明显是有脏数据存在,属于不可预料预知的异常,此处应该抛出非业务逻揖异常
                throw new FaultException("数据有问题,存在1个以上同用户名的用户!");
            }
            user = users.get(0);
            if (!user.getPassword.equals(password)) {
                //密码不正确,此处应该抛出业务逻揖异常
                throw new ServiceException("密码错误");
            }
        } else {
            //用户不存在,此处应该抛出业务逻揖异常
            throw new ServiceException("用户名不存在");
        }
        return user;
    }
}

这个例子中,象用户名不存在和密码错误属于可预知的异常,属于正常的将会,因此抛出业务逻揖异常,而根据用户名可查出一个以上的用户这种状况,正常状况下是不该该出现的,说明数据库中存在有脏数据,这种状况不该该是可预知的状况,程序员不该该去处理这种异常,因此此处应该抛出非业务逻揖异常。框架

固然也能够经过返回状态码的方式来处理业务逻揖的异常状况,好比:性能

/*
*由于通常登陆后都须要返回用户对象,因此这边须要特地写一个类来封装用户类和状态码
*/
public class ResultWrapper {
    private User user;
    //1-表示正常,2表示用户名不存在,3表示数据异常,.....(固然这边也能够用枚举来处理)
    private int resultCode;
    //get set方法
    .....
}
public class UserService {
    .....
    public ResultWrapper login(String username, String password) throws ServiceException {
        ResultWrapper result = new ResultWrapper();
        User user = null;
        //根据帐号获取用户对象
        List<User> users = userDao.queryByUsername(usernmae);
        if (!users.isEmpty()) {
            if (users.size() > 1) {
                //根据用户名可查到1个以上的用户,这明显是有脏数据存在,属于不可预料预知的异常
               result.setResultCode(3);
            }
            user = users.get(0);
            if (!user.getPassword.equals(password)) {
                //密码不正确
                 result.setResultCode(4);
            }
            result.setResultCode(4=1);
            result.setUser(user);
        } else {
            //用户不存在,此处应该抛出业务逻揖异常
            result.setResultCode(2);
        }
        return result;
    }
}

这也是一种处理方式,具体使用见仁见智了,由于使用异常确实代价比较大(性能上的代价,java语言中处理异常的性能代价),但我仍是比较喜欢使用异常的方式来处理业务逻揖异常,主要是基于如下缘由:spa

  1. 主线比较明确,使用异常来处理业务逻揖能够突出主线,好比登陆的场景,正常状况下就是使用名密码登陆成功,而若是使用状态码来区分的话从业务层面上来讲这几种状态都是平级的,最后都是经过return一个结果回去。设计

  2. 代码比较简洁,使用异常来处理省了一个外层的包装ResultWrapper,这边只是一个例子,正常项目若是要用这种方式的话就会产生很是多的包装类的,而用异常只须要两个异常类便可code

  3. 调用方处理简单,好比在Action中调用的话,程序员就不须要写一堆的if else了,只须要catch一下ServiceException便可(FaultException是继承RuntimeException的不须要特地的catch)
    orm

相关文章
相关标签/搜索