Which design template to use for my use?

I use the case when the input is given by parameters (for example, A, B, C, D) and data (for example, XYZ). Based on the parameters (A, B, C, D) I have to process the data (XYZ) and respond back. The processing logic can be unique or general based on the parameters (say, do something # 1 only when A, do something # 2, when A and C, do something # 2, when B, C and D etc.). I may also need to maintain a processing order.

The current implementation is based on if-else loops. I am considering a chain of responsibility, pipeline design schemes. But is there any other suitable design template for the above task?

An example of using if-else blocks:

I / P: A = {A1, A2, A3}, B = {B1, B2, B3}, C = {C1, C2, C3}, D = {D1, D2, D3} and XYZ = "Foo"

if (A == A1) { //dosomething-A1 if (B == B1) { //dosomething-B1 if (C == C2) { //dosomething-C2 } } else if (B == B2) { //dosomething-B2 } if (C == C2) { //dosomething-C2 if (D == D1) { //dosomething-D1 } else if (D == D3) { //dosomething-D3 } } } else if (A == A2) { //dosomething-A2 ... } else if (A == A3) { //dosomething-A3 ... } 
+5
source share
4 answers

The chain seems to work very well if it is reused. Another option is to use handlers stored on the map, where the key is the appropriate parameter value. This works well for a limited set of possible values ​​passed as parameters. You will get something like:

 handlers.get( a ).handle(XYZ) 

So, completely, if not less, on your part. But then again, this is not suitable for all purposes.

+4
source

Look for something like a team template. Based on these parameters, it is necessary to process. Internal realization should not be exposed outside. Thus, from the point of view of the open interface, it must accept parameters and data, and the command template must determine which method to execute based on the parameters.

+3
source

Without a real word, it's hard to say, but most likely you can reduce the size of your if / else tree with a good class hierarchy.

Polymorphism will make it more object oriented.

0
source

Your list of if-then-else statements reminds me of a rule-based system. The basis of the rule is essentially a database containing the rules of the form Condition -> Action . An implementation of a condition in Java 8 might look like this:

  @FunctionalInterface interface Condition { boolean matches(A a, B b, C c, D d); } 

For Action you can just use Runnable . Based on your code, a rulebase definition can be defined as follows:

 static final Map<Condition, Runnable> BASE = ImmutableMap.<Condition, Runnable>builder() .put((a, b, c, d) -> a == A1, () -> doSomethingA1()) .put((a, b, c, d) -> a == A1 && b == B1, () -> doSomethingB1()) .put((a, b, c, d) -> a == A1 && b == B1 && c == C2, () -> doSomethingC2()) .put((a, b, c, d) -> a == A1 && b == B2, () -> doSomethingB2()) .put((a, b, c, d) -> c == C2, () -> doSomethingC2()) .put((a, b, c, d) -> c == C2 && d == D1, () -> doSomethingD1()) .put((a, b, c, d) -> c == C2 && d == D3, () -> doSomethingD3()) .put((a, b, c, d) -> a == A2, () -> doSomethingA2()) .put((a, b, c, d) -> a == A3, () -> doSomethingA3()) .build(); 

To use this rule base, you can simply define the following method:

 static void evaluate(A a, B b, C c, D d) { BASE.entrySet().stream() .filter((entry) -> entry.getKey().matches(a, b, c, d)) .forEach((e) -> e.getValue().run()); } 

Lets name it as follows:

 evaluate(A1, B1, null, null); // executes doSomethingA1() and doSomethingB1() 
0
source

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


All Articles