void ? throw Exception ? Or side-effect ?

原创
2016/12/02 21:16
阅读数 50

在面向对象的编程中,行为会被封装成类的方法,暴露方法的行为结果一般有三种方式:

1.返回一个处理结果对象(Object),非void

2.抛出不同种类的异常,调用者通过判断异常来区分处理结果

3.修改入参的对象,即通过方法的副作用来暴露方法的处理结果,此种方法一般用于返回多个对象

首先我们最常用的是第一种方式,即方法处理完成之后,返回一个结果,该结果的如何使用以及该结果的作用域完全由使用者来决定. 由于返回的是明确的结果,故而方法在执行过程中,不会影响调用者的执行过程,相对于throw exception来说.

自然,throw exception则一般是用户尽快结束程序.往往是用于发生了不可修复的异常.在一个业务流程中,某一环节发生异常,程序继续执行已没有任何意义时.当然,还有部分异常时强制性的,比如读取文件等异常.从设计目的来说,如果是为了控制业务流程,不建议使用exception,建议使用明确的返回结果,调用者可以根据返回结果来决定是否继续执行,以及如何执行.

那么通过方法的副作用来完成业务逻辑,是否可取?不可否认的,存在即有它的作用.通过副作用来实现业务逻辑,与面向对象的封装是背道而驰的.一个行为,不修改传入的数据,返回一个新的结果,不对调用者的任何数据进行修改,实现数据上的隔离,保证各个行为(method)之间是相互独立的.行为之间的相互独立,无论是迁移还是重构,都会变得轻松.另外,使用副作用来完成业务逻辑时,还要考虑引用传值,以及资源竞争(比如来修改文件或者数据库中的数据)的问题.

下面附上代码片段来说说exception控制业务流程的一些问题:

package com.test.demo;

/**
 * yingyinglicai.com Inc.
 * Copyright (c) 2013-2016 All Rights Reserved.
 *
 * @author ZhangZhong
 * @version v 0.1 2016/11/27 10:44 Exp $$
 */
public class CAbc {

    public boolean method_a_return(){
        System.out.println("method_a_return");
        return true;
    }

    public void method_a_exception() throws Exception {
        throw new Exception("method_a_exception");
    }

    public void method_a_runtime_exception(){
        throw new RuntimeException("method_a_runtime_exception");
    }

    public boolean method_b_return(){
        System.out.println("method_b_return");
        return true;
    }

    public void method_b_exception() throws Exception {
        throw new Exception("method_b_exception");
    }

    public void method_b_runtime_exception(){
        throw new RuntimeException("method_b_runtime_exception");
    }
}

package com.test.demo;

/**
 * yingyinglicai.com Inc.
 * Copyright (c) 2013-2016 All Rights Reserved.
 *
 * @author ZhangZhong
 * @version v 0.1 2016/11/27 10:44 Exp $$
 */
public class CXyz {

    public boolean method_x_return(){
        System.out.println("method_x_return");
        return true;
    }

    public void method_x_exception() throws Exception {
        throw new Exception("method_x_exception");
    }

    public void method_x_runtime_exception(){
        throw new RuntimeException("method_x_runtime_exception");
    }

    public boolean method_y_return(){
        System.out.println("method_y_return");
        return true;
    }

    public void method_y_exception() throws Exception {
        throw new Exception("method_y_exception");
    }

    public void method_y_runtime_exception(){
        throw new RuntimeException("method_y_runtime_exception");
    }
}
package com.test.demo;

/**
 * yingyinglicai.com Inc.
 * Copyright (c) 2013-2016 All Rights Reserved.
 *
 * @author ZhangZhong
 * @version v 0.1 2016/11/27 10:49 Exp $$
 */
public class CBiz {

    private CXyz cXyz;

    private CAbc cAbc;

    /**
     * 当发生异常,立即终止方法
     * @return
     */
    public boolean flow_return_when_exception() {

        try {
            cAbc.method_a_return();

            cXyz.method_x_return();

            cXyz.method_x_exception();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 当发生异常,继续执行其他部分异常
     * @return
     */
    public boolean flow_no_return_when_exception() {
        try {
            cAbc.method_a_return();

            cXyz.method_x_exception();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("no return even exception but continu");
        }

        cXyz.method_x_return();

        return true;
    }

    /**
     * 发生异常,继续执行,若再发生异常,仍旧继续执行
     * @return
     */
    public boolean flow_no_return_when_exception_further() {

        try {
            cAbc.method_a_return();

            cXyz.method_x_exception();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("no return even exception but continu");
        }

        cXyz.method_x_return();

        try {
            assert cAbc.method_b_return();

            cXyz.method_y_exception();

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("no return even exception but continu");
        }

        cXyz.method_y_return();

        return true;
    }

    /**
     * 明确在某些步骤执行失败时,终止
     * @return
     */
    public boolean clear_return_when_false() {
        try {
            assert cAbc.method_a_return();

            cAbc.method_b_return();

            cXyz.method_x_return();

            assert cXyz.method_y_return();

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}

本文作者:猫小鞭

展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部