-2

Case: Several methods with same params validation inside, like:

public Response method1(...params...)
{
    if (someCondition)
    {
        //do some stuff with side effects
        ...
        return Response1;
    }
    if (someCondition2)
    {
        //do another stuff with side effects
        ...
        return Response2;
    }
    if (someCondition3)
    {
        //do another stuff with side effects
        ...
        return Response3;
    }
    // Do something
    return Response4;
}

and

public Response method2(...params...)
{
    if (someCondition)
    {
        //do another stuff with side effects
        ...
        return Response1;
    }
    if (someCondition2)
    {
        //do another stuff with side effects
        ...
        return Response2;
    }
    if (someCondition3)
    {
        //do another stuff with side effects
        ...
        return Response3;
    }
    // Do something 2
    return Response4;
}

Etc.......... How Can i avoid duplication without throwing exception?

UPD: I try to explain why it is not duplicate of Style for control flow with validation checks : In this case in both functions after "someCondition" validation we have some code with side effects in function, not just return response, so i cant just make some method (Specification pattern) that do validation and return response because of additional logic after validate param.

  • 1
    Possible duplicate of Style for control flow with validation checks – gnat Sep 5 '19 at 20:39
  • If the Boolean cond has to be true, what's the point of passing it? That validation should be eksewhere – user949300 Sep 6 '19 at 16:30
  • @user949300 Its not real code, just some mock example. I removed that param, thanks. – quad478 Sep 6 '19 at 21:12
  • After one month this question still has poor names, variables that appear out of nowhere, which make it very hard to come up with good answers. – user949300 Oct 7 '19 at 18:56
  • 1
    @quad478 Where do the "someConditions" come from? Are they part of the parameters, or are they calculated in the function? – user949300 Oct 7 '19 at 23:21
3

My suggestions, in my personally-recommended order:

Option 1: Assuming those primitives are often used together, wrap them all in an object that models their collective value to the problem domain, and perform the validation in that class. If you can, make it a struct, so you don't require null checks in both methods.

Option 2: Handle the validation in calling code that is in a higher tier, layer, or level of abstraction, assuming that reduces the duplication

Option 3: Using Aspects (aop).

Aspect-oriented programming specializes in handling cross-cutting concerns that object-oriented programming can sometimes struggle with, such as logging, validation, or error handling. It works through the use of 'Aspects' which are pieces of code that can be applied to multiple methods, classes, or even assemblies. For example, in your case, you might have a 'ParameterValidationAspect' that, when applied to a method, validates the method arguments and determines whether the method should be executed or if another value should be returned instead.

The code can vary greatly based on the implementation, but a common pattern is to have an attribute that is applied to a parameter, method, class, or assembly, similar to this sample:

[LogMethodEntryAndExitAspect]
public void Method1()
{
  // no code in here, but aspect logs before method is entered and after method exits
}

[ValidateParametersAspect<ResponseType>]
public ResponseType Method2(string p1, int p2)
{
   //ValidateParameters aspect will perform the validation and return the appropriate response.

   //Other logic
   return new ResponseType();
}

The exact mechanism aspect-oriented programming uses to insert logic into methods can vary, based on the implementation you go with. Generally, there's three mechanisms an aop library uses :

  1. Inserting code after compilation by modifying the byte or ilsm code (C#'s PostSharp uses this).
  2. Intercepting method calls with a wrapper object.
  3. Using reflection to modify the class at runtime (can overlap a bit with #2)

Some implementations might provide hooks for you to tap into, like 'PreMethodExecute', 'MethodExecution', 'OnException', etc.

I enjoy the concept of Aop, but its complexity can be substantial, especially in the beginning of the learning curve. It's difficult for a single developer to introduce it into a system, and pursuing this type of solution should have buy-in across your teams.

  • Thank you very much for your answer. Interesting in option without aspects. Could you give some example, how i can return value from another layer? – quad478 Sep 6 '19 at 10:10
  • I've included some additional aop information; unfortunately, the exact constraints and varies a great deal between different implementations, so what all you can accomplish can vary. For that reason, I've tried to keep my answer theoretical, especially since I'm not very familiar with Java's aop library ecosystem. – JohnsonCore Sep 6 '19 at 13:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.