Why the first instruction we learn to program should be the last to use.
Nobody uses GOTO instruction anymore and few programming languages still ...
For further actions, you may consider blocking this person and/or reporting abuse
This is an incredibly narrow view on programming.
goto
s, which is how CPUs make decisions.if
-statements are the simplest and easiest way to describe some logic². In most cases, this doesn't change, so it's much more viable to only remove them as a refactoring step or if it's very clear from the start that the logic will have to be extended.Have a look at the following code³:
It should become obvious that the mapping from a rating to the minimum age should be thought of as a constant, not as program logic. Encoding this data into the source code is the actual code smell, not the statement used to do so. Building classes around this only hides the real issue under a heap of complexity instead of fixing anything.
This is a very common pattern in naive OO design: Bury obvious flaws under a convoluted class-system and hope to gain some extensibility by breaking up the code.
Here's what the code should really look like:
There is exactly one if, and it encodes business logic. The data is extracted into a data structure that could at any time be trivially moved into a JSON or YAML file for easier configuration.
¹ This isn't always relevant, but it often enough is that it shouldn't be ignored. It always depends on the language and compiler, but if performance is critical, the code will likely be C or something comparable.
² "if this than that" sentences are how we usually communicate conditional actions outside programming, so it's safe to assume it's a very natural way for humans to think about them.
³ Written in Lua because I don't enjoy typing as much as in my Pascal days.
Hello and thank you for your detailed comments.
1 - Performance and good design are sometimes in tension. In my experience performance issues should be delayed as possible. Unless you are building a time critical software good designs should always be prioritized.
You might be doing Premature Optimization (which is a code smell)
Code Smell 20 - Premature Optimization
Maxi Contieri ・ Nov 8 ・ 2 min read
Modern Virtual machines make a lots of inline optimizations so I always suggest making a benchmark before guessing which one will be faster.
2 - I don't know what is normal. This is the way were taught at school and universities. But software has a lot of errors and bad quality and that is the article thesis. Don't trust normal.
Logic extension should be made following SOLID principles. Not adding IFs.
Are you very sure if this than that is common among not developers? I don't really think so on accidental IFs. Try talking with non developers on NULLs and IFs. You might get surprised.
3 - I don't know anything about logic and data. I think they are related to old school structured programming. Which is fine. I write articles con OOP and they only predicate on behaviour.
I think you are confusing accidental concepts (like JSON or YAML) with essential ones (behavior). I don't see a problem on that.
I just think we are talking with different design points of view.
Your comment states data is important and should be configured externally. I say data is accidental and we should never care about it at all. My humble opinion is that we should view objects related to behavior and we should encapsulate what you call data following information hiding guidelines.
This is my point of view on models:
What is (wrong with) software
Maxi Contieri ・ Oct 8 ・ 4 min read
Related to this topic:
This is a very common pattern in naive OO design: Bury obvious flaws under a convoluted class-system and hope to gain some extensibility by breaking up the code.
Extensibility is key when you design very large systems with millions of code lines (as I do). Breaking up the code and refactoring is the only way of evolving the system and IFs are always blockers and defects source.
I Appreciate the time you took to comment on the note.
Regards
I 100% agree. To clarify, my point was just that performane can be a reason to prefer
if
statements, but only after the code has been found to be a performance bottleneck. Prematurely using low-level constructs where a higher-level abstraction would improve code quality is, as always, bad style.Depending on the situation, I am very much convinced. People say "If the weather is good, we can go to the park tomorrow", not "tomorrow we can do a weather-appropriate activity, where going to the park would be appropriate for sunny weather". This obviously isn't necessarily universal, but it does seem like a tendency.
I did mention those, but only to give a specific example. My main point is independent of data description formats though: The mapping from Rating to minimum age, is (or rather falls on the side of) data, not logic
On the contrary: Data is the only thing we should care about. After all, the only purpose of any program is to take input data and turning it into output data.
Our opinions seem to run parallel here. Looking back at my code example, you end up getting the same level of extensibility. It is easy to add another rating by appending an entry to the map. This is certainly also achieved by your method of encoding this relationship in objects, but my main point of criticism is that it encodes what I would consider a constant¹ as an object method.
¹ note that I don't consider a numeric constant like
42
to be any different from a hugely complex constant data-structure. The defining factor is it's immutability during program execution.What I consider naive with that pattern is that it adds complexity to the code. If you were to draw flow-charts of both implementations, one of them ends up showing the relationships, while the other treats them as additional input data.
Not in my experience at least. Assuming performance is not critical, refactoring code with many conditionals can be done in many ways and I personally prefer representing the complex decision logic using data structures. This sometimes goes almost full-circle: depending on the language, data-structures can contain code (usually in the form of functions), which then looks surprisingly similar to an object, which is ultimately just a handle for a collection of behaviours, not unlike a data-structure containing functions.
Hi again.
We agree to disagree :)
I think the main disagreement comes from this perception of software.
On the contrary: Data is the only thing we should care about. After all, the only purpose of any program is to take input data and turning it into output data.
I don't care about data because I see software as a model and predictor and data is accidental.
If we were to design a weather forecaster I would not see temperature and pressure indicators as data flowing into the system. I'd like to see the model as a simulator and predictor of actual conditions.
So out forecasted data like estimated temperature, wind speed and thus would be accidental. What would be essential (IMHO) is the model behaving like real weather.
If you get too coupled to data you cannot change them as long as requirements change. And I personally think end users don't care about data. It is us, developers, who care too much about that. User wish a system do what they would need to achieve manually.
You prefer representing the complex decision logic using data structures and this is fine. you want to see all the information centralized and this is tradeoff decision. This is the structural programming approach and is very good.
I'm just pointing out there other ways of simulating real world.
Again. All my opinions
Definitely. But either way, I still find it very interesting to see how someone else thinks about software systems completely differently, as I don't believe neither of us is inherently more "right" or "wrong" than the other.
To end on a positive conclusion: I think we can extrapolate from this that OOP, with its emphasis on systems and behaviours and FP, with its contrasting emphasis on data flow and transformations can both be the right or wrong tool for any individual developer and/or team, depending largely on how they tend to think about computation.
Not that this is a groundbreaking deduction, but it's something that's easily forgotten :D
It is very nice learning with you
I think there are no silver bullets.
different projects need different solutions
This solution is way cleaner, and easier to understand than the OP. I created an account just for this post. Over engineering a solution just to get rid of some if statements is not an improvement.
It is just an example.
Replacing one IF with a hierarchy might seem over engineering.
But this is one short example to fit a small article.
In big systems (I will not put tons of code here) the impact is huge.
I'm showing a technique with its benefits and the second example is definitively over design. I also provided a rule to decide (IMHO) when it's worth it and when it isn't
IFs seem to be very easy and more readable to read. This is exactly what happen with all coupling issues like Nulls, Globals, Singletons and so. They are very easy to read on a isolated piece of code. But this coupling brings lots of defects and prevent big systems to evolve.
While there may be some good ideas here, I'm concerned that this is going to promote "Real Programmers Use Butterflies"-flavored overengineering. I've seen countless atrocities committed in the name of eliminating perfectly reasonable
if
statements.But then, one should be wary of anything stated as "
<x>
Considered Harmful". It's almost always either (1) an overbroad generalization based on a specific problem, or (2) an attempt to promote the latest Clever Solution™.The author may say, "Well, no, I'm not really advocating getting rid of all
if
statements", but if that's the case, the title and article structure aren't a responsible or accurate reflection of the point, even to the brink of being guilty of "clickbait".Thank you, Jason
I'm aware of over engineering and overbroad generalization. That's why the article has a counterexample on it and warns against abuse.
Title is a bit clickbait. But the word 'annoying' has two meanings
1) All the Ifs are annoying and should all be removed.
2) We need to remove JUST the annoying ones.
The article's spirit is the second one.
I figured as much, but you have to consider how your readers MIGHT perceive it. Skimming is prevalent, and this doesn't skim the way you'd want.
Certainly I'll edit the conclusion to stress this out.
Thank you for your feedback!
Congrats! You created OOP Spaghetti code!
Leaving the If Else would have been more readable and thus more maintainable than this forest of Classes.
As for me, in the FP style - following Wii's answer:
How about all the other arguments about extensibility, new business rulet etc? Are they also 'Pasta' ?
I dunno man, your making the if statements look pretty simple.