设计接口时应该如何设计业务异常?

本文为原创,转载请注明

作者:cha1R(tanjiayqq)

Java里异常分两种,一种是检查(checked)的,一种是非检查(unchecked)的。

非检查以RuntimeException作为典型代表,它有一个特点就是我们可以不用捕捉它,如果没有捕捉它,它会一直往上抛直到main()方法处理,从而退出整个程序。注意如果是多线程的话,它并不会在main()方法终止程序,它会一直往上抛直到run()方法,而run()方法没有捕捉它的话会终止线程。

作为业务异常,是要反馈给用户的,所以我们不希望发生任何终止线程或者终止程序的代码。所以定义业务异常,我们一般使用检查的(checked)异常,定义一个异常非常简单,只需要写一个简单的类继承Exception即可。

public class InvalidAccount extends Exception{
    private static final long serialVersionUID = 1L;
    public InvalidAccount(){
        super("无效的账户");
    }
    public InvalidAccount(String msg){
        super(msg);
    }
}

那么我们一般什么时候需要设计业务异常呢?从我的经验来看,一般是设计业务接口的时候需要考虑这个接口会引发的业务异常。

假设设计一个登陆业务接口:

    /**
     * 登录
     * @param username 用户名
     * @param password 密码
     * @return 是否登录成功*/
    boolean login(String username,String password);

显然这个接口没有抛出异常,那么我们在还没实现接口的情况下,该如何考虑这个接口会发生什么样的异常?

其实我们很难全面地预测到它会发生一些什么,但是我们只需要考虑业务异常,业务异常是什么?即应用异常(如 权限不够等),这类异常需要通过前台反馈给用户,友好提示用户当前操作异常。

最大的特点就是,这个异常一定是由于当前接口调用不当(即用户操作不当,因为它接收的是用户输入的数据)造成的,那么最直接的思路就是从传入参数入手:

从登陆接口来看,传入的是用户名和密码,那么我们可以抛出一个“无效的用户”或者抛出“无效的用户名”和“无效的密码” 异常,其他的都不用抛出,因为它并不是由调用者引发的,在方法内部处理完就行。

再来看看一个我们一个项目的业务接口,评论微博:

    /**
     * 评论
     * @param userId     被评论的用户的ID
     * @param weiboId     被评论的微博的ID
     * @param content     评论内容
     * @return
     */
    boolean comment(String userId,String weiboId,String content);

定义这个方法的异常还算比较简单,从参数入手

userId:用户不存在异常

weiboId:微博不存在异常

content:内容包含敏感词汇异常,内容超出字数限制异常。 或直接用一个 内容不合法异常

这些都是可以抛出的异常。

但是有时候一条微博可能被设置为 “不可评论”,那么我们是不是要再跑出一个“不可评论异常”?这个完全不必抛出,因为我们抛出业务异常是用来反馈给用户看,从而让用户做出相应处理,但是这种不可改变的情况完全没必要交给用户决定如何处理,只需要在方法内部抛出RuntimeException,UI层统一捕获,提示一下即可。

最后介绍一个学习网站,比较适合初学者,视频略多:Here

原文地址:https://www.cnblogs.com/cha1r/p/3424597.html