Rediscovering the concept of Flow Control

Alan George Meile
Apr 17 · 4 min read

This story is a reflection about how I used to follow certain patterns without giving them any thought. It starts with a justification, followed by a step-by-step introduction to what the new approach looks like and ends with a conclusion.

Photo by kazuend on Unsplash

During my apprenticeship and studies, the Flow Control concept has been hammered into my head by my peers and superiors. I remember them saying things like goto statements are evil, use guard clauses, don’t use exceptions, use md5 + salt to hash your password, you name it. The answer to my questions concerning the previously mentioned statements was always because it is best practice. At that time, I was using most of my mental capacity to solve the problems my code was causing. They consisted mainly of Stackoverflow Exceptions, Out of memory Exceptions, code not compiling, and don’t get me started on the Cookies and Cross-Origin problems I faced. Not using goto statements and introducing guard clauses was the least of my concerns.

Different types of validity

Formal Validity

In the course of this adventure, I use the word formal validity a lot. What I mean is that a provided argument in a function conforms with certain rules. For instance, data can be checked if a property is missing or if a value is within certain range boundaries.

Contextual Validity

I also use the word contextual validity. By which I mean that data is also valid in an uncertain context. For example, I can try and update a formally valid record in the database. If no record with the provided identifier exists, the write operation will fail. The object is formally valid but is contextually invalid.

Changing my approach

Now, after years of writing code, I gained further understanding. I have more time to focus on code readability and view code on a higher abstraction level. One of the things I notice is that I am so used to writing guard clauses my whole codebase is littered with them.

Other than the code enforcement rules and the haunting whispers of my former peers, I have no idea why I should write code in this manner. I have become a brainless coding monkey in this aspect.

Of course, I understand what the guard clauses are doing. They prevent a possible null exception when using user or address and make sure that address is formally valid.

But is this the right place to do this kind of validation?

I am also repeating the user check in the update method, which violates the DRY rule.

Let’s put the previous code into context.

Believe it or not, but I drew this myself.

For example, the HTTP API, where the received JSON object is parsed and assigned to an object. But only if the data is formally valid, or else it throws an exception. Every function expecting an object of that type can assume that it is formally valid and doesn’t need to validate it.

You might think this is dangerous. What if another developer uses one of your methods and receives a null exception? Well, then I hope they will do the same things as they would when receiving an ArgumentNotNull exception → Change the code and make it work.

Middleware

In the system’s entry point, I parse and validate the incoming data once and throw an exception if it is false. Does this mean I have to litter my code base with try-catch blocks? No, I can introduce an exception middleware with a defined exception hierarchy. Then based on what Exception you catch, you can create the appropriate ActionResult.

What about failed context validity

It is to be expected that API consumers provide you with data that is contextually invalid.

How do I handle an update request with an invalid identifier?

Well, I need to make my intention clear in my method signature. One widely accepted way of doing so is to use a result pattern. Introducing this concept greatly increases readability.

The latter communicates that the method can succeed or fail. In comparison, the first method looks like it will always return a user.

Conclusion

Following so called best practises brainlessly will most likely litter your code base. Take the time to think about why you should do something and don’t do it just because your peers and superiors say it is best practice. In my case I noticed that guard clauses don’t need to be used everywhere.

The Coding Adventure

Everything is progressing at a pace hard to follow, leaving a jungle of mysteries to explore…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store