How to consolidate validation and throwing exceptions in Java?

I am implementing an interface that defines a method that can throw an exception if the parameters are invalid. What constitutes valid parameters depends on the implementation class. The interface also defines a method isValid()that can be used to check parameters, but returns a logical, not an exception. I found that implementing both methods will cause a lot of duplication. Consider this example:

public class Something implements SomeInterface {

    // Other class stuff

    public void doTheThing(SomeParameter sp) throws SpecificRuntimeException {
        if(sp == null) throw new ParameterCannotBeNullException();
        if(sp.getNonZeroInt() == 0) throw new ShouldBeNonZeroException();
        if(!sp.someOtherCondition()) throw new SomeConditionNotMetException();

        ...
    }

    public boolean isValid(SomeParameter sp) {
       if(sp == null) return false;
       if(sp.getNonZeroInt() == 0) return false;
       if(!sp.someOtherCondition()) return false;

       ...
       return true;
    }
}

The problem is that the checks of both methods must be consistent and essentially duplicated by logic. I tried to consolidate the checks so that both methods use the same checks, but the behavior still persists. Some things that I considered:

  • doTheThing() if(!isValid(sp) throw new RuntimeException();
  • , , checkParameter() isValid() do: try { checkParameter(sp); return true; } catch (SpecificRunTimeException e) { return false; }

1. , , . 2. ... -. , -, , ( , , .... , ?). , ?

?

+3
5

, isValidParam, bean :

class ValidBean {
  private boolean isValid;
  private Exception exceptionOnInvalid;
  public ValidBean(boolean isValid, Exception exceptionOnInvalid) {...}
  // accessors
}

:

private ValidBean isValidParam(SomeParameter sp) {
       if (sp == null) {
          return new ValidBean(false, new ParameterCannotBeNullException());
       }
       if (sp.getNonZeroInt() == 0) { 
         return new ValidBean(false, new ShouldBeNonZeroException());
       }
       if (!sp.someOtherCondition()) {
          return new ValidBean(false, new SomeConditionNotMetException());
       }
       return new ValidBean(true, null);
    }

:

public boolean isValid(SomeParameter sp) {
 return isValidParam(sp).isValid();
}

public void doTheThing(SomeParameter sp) throws SpecificRuntimeException {
  ValidBean validbean = isValidParam(sp); 
  if (! validBean.isValid()) {
      throw validBean.getExceptionOnInvalid();
  }
  ...
}
+2

, , , , :

private boolean isValidInternal(SomeParameter sp, boolean throwIfInvalid)
    throws SpecificRuntimeException

isValidInternal true doTheThing false isValid.

: , isValidInternal, , false, throwIfInvalid.

+1

; API-, , , .

, isValid() doTheThing()? , , try/catch, isValid() .

( , , , .)

isValid(), , try/catch; , , , !

+1

" " . ; .

, , isValid().

, , , IllegalArgumentException , . , .

0

, , , , .. API / , /. , API , , .

PS: You should not use runtime exception types in a method declaration throws. But you must specify these exceptions at runtime in the Javadoc documentation @throws.

0
source

Source: https://habr.com/ru/post/1728905/


All Articles