Validation of input parameters are at the beginning of the method. If the method has code after validation, then it has not a single responsibility. How can we separate validation code for input parameters and rest of the code?
Example with proxy
The interface:
public interface Foo { Optional<Integer> divide(int a, int b); }
The implementation:
public class FooImpl implements Foo { @Override public Optional<Integer> divide(int a, int b) { return Optional.of(a / b); } }
The validation:
public class FooValidation implements Foo { Foo foo; List<String> errors = new ArrayList<>(); public FooValidation(Foo foo) { this.foo = foo; } @Override public Optional<Integer> divide(int a, int b) { if (b == 0) { errors.add("Second parameter is 0 and it is not allowed"); return Optional.empty(); } return foo.divide(a, b); } public List<String> getErrors() { return errors; } }
Tests
@Test public void test_divide() throws Exception { Foo foo = new FooImpl(); int result = foo.divide(5, 2).get(); assertEquals(2, result); } @Test public void test_with_validation() throws Exception { Foo foo = new FooImpl(); FooValidation fooValidation = new FooValidation(foo); boolean result = fooValidation.divide(5, 0).isPresent(); assertFalse(result); assertEquals("Second parameter is 0 and it is not allowed", fooValidation.getErrors().get(0) ); }
Conclusion
When you have a dynamic validation, you have to change only the class with validation logic.You can test validation logic and rest of the logic of the method separated.