Why not use exceptions as regular flow of control?

后端 未结 24 1820
心在旅途
心在旅途 2020-11-21 07:30

To avoid all standard-answers I could have Googled on, I will provide an example you all can attack at will.

C# and Java (and too many others) have with plenty of ty

24条回答
  •  鱼传尺愫
    2020-11-21 08:07

    Josh Bloch deals with this topic extensively in Effective Java. His suggestions are illuminating and should apply to .Net as well (except for the details).

    In particular, exceptions should be used for exceptional circumstances. The reasons for this are usability-related, mainly. For a given method to be maximally usable, its input and output conditions should be maximally constrained.

    For example, the second method is easier to use than the first:

    /**
     * Adds two positive numbers.
     *
     * @param addend1 greater than zero
     * @param addend2 greater than zero
     * @throws AdditionException if addend1 or addend2 is less than or equal to zero
     */
    int addPositiveNumbers(int addend1, int addend2) throws AdditionException{
      if( addend1 <= 0 ){
         throw new AdditionException("addend1 is <= 0");
      }
      else if( addend2 <= 0 ){
         throw new AdditionException("addend2 is <= 0");
      }
      return addend1 + addend2;
    }
    
    /**
     * Adds two positive numbers.
     *
     * @param addend1 greater than zero
     * @param addend2 greater than zero
     */
    public int addPositiveNumbers(int addend1, int addend2) {
      if( addend1 <= 0 ){
         throw new IllegalArgumentException("addend1 is <= 0");
      }
      else if( addend2 <= 0 ){
         throw new IllegalArgumentException("addend2 is <= 0");
      }
      return addend1 + addend2;
    }
    

    In either case, you need to check to make sure that the caller is using your API appropriately. But in the second case, you require it (implicitly). The soft Exceptions will still be thrown if the user didn't read the javadoc, but:

    1. You don't need to document it.
    2. You don't need to test for it (depending upon how aggresive your unit testing strategy is).
    3. You don't require the caller to handle three use cases.

    The ground-level point is that Exceptions should not be used as return codes, largely because you've complicated not only YOUR API, but the caller's API as well.

    Doing the right thing comes at a cost, of course. The cost is that everyone needs to understand that they need to read and follow the documentation. Hopefully that is the case anyway.

提交回复
热议问题