How to get rid of many if/else?

Good day!

There is something like this pseudo code for some calculations:
IF Condition 1 THEN
 Doing the calculations the first method
ELSE IF Condition 2 THEN
 Do the calculations the second method
ELSE IF Condition 3 THEN
 Make calculations the third method
ELSE
 Here access a database and find the last valid value
END


The point is that you need to do the calculations. We choose to do the first method if the first did not work, then you need to try the second, or third try, but if all methods have not produced successful results, it is necessary to access the Database and where to find the last successful value.

Such that if/else code maybe around 20, and there is a mixture of different logic: the business logic and the logic of the calls to the database.

Do you know how "beautiful" to organize such code? Maybe some design patterns can be applied?
April 3rd 20 at 17:24
6 answers
April 3rd 20 at 17:26
Solution
class CalculationData;

abstract class Calculation 
{
 public function calculate(CalculationData data);
}

class CalculationQueue 
{
 public function addCalculation(Calculation calculationVariant, int priority);

 public function calculate(CalculationData data) { 
 for (c in calculations) {
 if(res = c.calculate(data)) return res;
}
}
}
@Royal, Indeed, a good decision!
Thank you! - nayeli_Bli commented on April 3rd 20 at 17:29
@nayeli_Bli, bad decision - alfredo.DAmore commented on April 3rd 20 at 17:32
@alfredo.DAmore, arguments? - Royal commented on April 3rd 20 at 17:35
@alfredo.DAmore,
bad decision

bad argument.

Yes, you essentially said nothing. Here are your answers to this question:

it all depends on how the conditions and actions to be performed.
Without the specifics of the answer can not be, except the obvious switch

Almost any question can be answered as follows: that all depends on the conditions. What you have to offer to replace if/else with switch does not change anything. But if I had to replace the swicth, you'd if/else suggested? Why not trinary operator "condition ? action 1 : action 2"?

Without knowing the details it could be a bad decision.
P. S. code, by the way, non

Well, actually, I thought it was just pseudo code... Surely you have it copied and tried to compile and run??

Now why the idea that code is good. Most likely @Royal showed the realization of the pattern "chain of responsibility", but not the essence... With this approach, the code can be broken down into small classes Calculationthat will perform exactly one task and no more. Each class will have its own dependencies, and only those that need it to perform their job. Also implementation of these classes can belong to different layers of an application, one will be implemented in the business layer, other infrastructure, etc. Also followed the principle of openness/closure, adding new behavior, you need to write a new heir from the grade Calculation.

Summing up, I would say that the idea is very good! If there is a better solution, then please show it to us! Personally, I am very interested to see your code. - nayeli_Bli commented on April 3rd 20 at 17:38
April 3rd 20 at 17:28
The obvious switch. There are in most languages.
@Lois_Boehm87, dislik by far ... - nayeli_Bli commented on April 3rd 20 at 17:31
@nayeli_Bli, I do not like - do not use, not forced - Lois_Boehm87 commented on April 3rd 20 at 17:34
@nayeli_Bli, it is obvious why dislike? - joanny_Rippin commented on April 3rd 20 at 17:37
@nayeli_Bli, https://www.sonarsource.com/docs/CognitiveComplexi... - joanny_Rippin commented on April 3rd 20 at 17:40
@joanny_Rippinwhy dislike? Yes, because the logic is the same it turns out that with if/else. - nayeli_Bli commented on April 3rd 20 at 17:43
@nayeli_Bli, for your piece of pseudocode is just a decision or pass logic divide and truncate logic too much in one place - joanny_Rippin commented on April 3rd 20 at 17:46
@nayeli_Bli, you may want to consider reducing the number of arguments for methods, and all without conditions will be solved - joanny_Rippin commented on April 3rd 20 at 17:49
@joanny_Rippin,
for your piece of pseudocode is just a decision or pass logic divide and truncate logic too much in one place

So I ask, how can we spread this logic, therefore, about the patterns and asked.
And what if to change the switch nothing will change. The same pieces of code with the same logic, in the same method...
Can't you understand?? - nayeli_Bli commented on April 3rd 20 at 17:52
@nayeli_Bli, well, you give not pseudocode, and so we're just wasting our time - joanny_Rippin commented on April 3rd 20 at 17:55
@nayeli_Bli, you need to check the conditions and depending on them to execute code. What you will come up except if-s and switch her? And should we even come up? No, you can create something like a named array, for example:
(pseudo-code)
array['method1'] = function(){ ... }
array['method2'] = function(){ ... }
array['method3'] = function(){ ... }

and then call the handler like this:
array[value]();
unless, of course, such language supports.
But:
1) unlike IFOV and switches, the implementation of such masochism varies greatly in languages
2) it makes the code much more complex and less understood for an outside specialist
5df06ddbbd155989963154.png - Lois_Boehm87 commented on April 3rd 20 at 17:58
@Lois_Boehm87, I wonder, if I asked what you can replace monstrous switch, you'd design if/else advised? - nayeli_Bli commented on April 3rd 20 at 18:01
@nayeli_Bli, Yes I would. This whole situation reminds about this:
Hello guys, I want to put my house window, but I don't want glass in it, suggest an alternative to glass
- Put plastic instead of glass
- Nah, don't want plastic, it is also transparent, and not visible from the outside, that it's not glass.
and in the end the decision is roughly the level of "Slapped on the bottom of the LCD panel and display it on the image from the camera placed outside." - Lois_Boehm87 commented on April 3rd 20 at 18:04
@Lois_Boehm87, thank you! Lifted the mood))) - nayeli_Bli commented on April 3rd 20 at 18:07
April 3rd 20 at 17:30
Usually diaper conditional expressions (especially multi-level) is a signal of the ability to use the pattern state. It is also useful to perform a decomposition of the code decision-makers and the code performing the calculations, i.e. the return is not the result of a calculation and performing of their behavior. Quite good if you wrap it in a maybe-typeto the calling code could delegate getting the value of default other code.
And if so: https://refactoring.guru/ru/replace-conditional-wi...
? - emmie commented on April 3rd 20 at 17:33
@emmie, this technique is used when the object has when creating a certain type, and throughout his life did not change, and if change, then it is necessary to use a pattern "state". Somewhere from Fowler this was written... - nayeli_Bli commented on April 3rd 20 at 17:36
@emmie, depends on the situation, like with any other patterns. If the architecture is the place where you will naturally face the factory, it is a good decision. But in the case of spherical project in vacuum, it is just replacement switch'and returns the value of the speed switch generates an object that returns a rate. - Filomena78 commented on April 3rd 20 at 17:39
April 3rd 20 at 17:32
We choose to do the first method if the first did not work, then you need to try the second, or third try, but if all methods have not produced successful results, it is necessary to access the Database and where to find the last successful value.
Your code does not match this description. In the above chain of if-else execution of any method does not depend on the result of the previous method, and the set of certain external conditions. For the chain you can use
result = tryMethod1() || tryMethod2() || ... || getFromDB();
@Marcelo.Keebl,
Your code does not match this description.

I agree, probably should be more focused on the description.
The pseudo-code I wanted to show a lot of if/else, certainly every programmer is found, and who are even proud of this code, like look what I have a complex logic... - nayeli_Bli commented on April 3rd 20 at 17:35
@nayeli_Bli, but why reinvent the wheel? Everything works, everything is logical and understandable, it is better to spend time developing new features, debugging and optimization of old than the invention of the Bicycle. - Lois_Boehm87 commented on April 3rd 20 at 17:38
@Lois_Boehm87, in some ways you are right, but I wouldn't want to mix business logic and the logic of database access. This logic must be at different levels - the level of business logic and infrastructure level.
Besides, if you write a unit test, it is necessary to abstract from any external source (in this case DB) - nayeli_Bli commented on April 3rd 20 at 17:41
April 3rd 20 at 17:34
it all depends on how the conditions and actions to be performed.
Without the specifics of the answer can not be, except the obvious switch
@alfredo.DAmore, that same person gave the answer - nayeli_Bli commented on April 3rd 20 at 17:37
@nayeli_Bli, so-so response. Without knowing the details it could be a bad decision.
P. S. code, by the way, non - alfredo.DAmore commented on April 3rd 20 at 17:40
@alfredo.DAmore, Yes, there is not so much the code itself, and the meaning of it.
It is a pity that you can't see it... - nayeli_Bli commented on April 3rd 20 at 17:43
@nayeli_Bli, but what is "meaning"? full bust ? so-so "meaning," I'll tell you.

full wrap too much in classes ... why ? the more that this obvious addition

public function addCalculation(Calculation calculationVariant, int priority);

looks like something not very nice. - trystan commented on April 3rd 20 at 17:46
@trystan, let it be your... - nayeli_Bli commented on April 3rd 20 at 17:49
@trystan, the point is not "complete overkill", and in calculations in the order specified by the priority in addition, as long as the calculation will not be successful. The same thing that TS in the original, but universal and without spaghetti.
Explicitly adding allows you to use the code in several places where the list of different calculations, without duplicating code.
In General, it is the PLO, to taste, it takes time and experience. - Royal commented on April 3rd 20 at 17:52
@trystan, for example, for classes of the business logic layer has a higher priority, and classes for working with the database level can be set lower.
In General the approach is flexible and simple in nature. This is its beauty. - nayeli_Bli commented on April 3rd 20 at 17:55
April 3rd 20 at 17:36
then looking for the conditions

if the condition is compared with a constant, and such conditions a lot I would use a dictionary (associative array) of values which would be function pointers

if the terms themselves are some calculations, then there is of course no too much is not enough.

Find more questions by tags Designing software