Breaking the if-else logic trap with the Rule-based design pattern

Breaking the if-else logic trap with the Rule-based design pattern

Overview

There are situations where you are presented to deal with legacy code or work upon modules that require you to return responses by matching the input on certain conditions this is a common situation represented by each software engineer in their day-to-day life.

We often choose to use if-else statements or switch statements to solve such problems. This approach is fine if you have like 1-2 conditions to deal with. But what if we have multiple conditions?

Bob likes to call this situation an if-else trap. Because if you have a lot of conditions to deal with there is a high chance these conditions will further increase as functionality increases and will make our code a piece of art "The Moaning Lisa".

Bob's use case

Bob's manager asked him to create a functionality that returns the status message for an asynchronous job triggered on some trivial conditions. The workers handling the job has complete information. The flow of requests is depicted as

No alt text provided for this image

For our convenience, we will keep the request in 4 states represented by ENUM

  1. ACCEPTED
  2. IN_PROGRESS
  3. FAILED
  4. SUCCEEDED

In order to provide the status messages to customers the request in each state reads the progress from different files which is elaborated in the pseudocode below

No alt text provided for this image

Advantages:

  • The code has high readability
  • Less effort to write the code.

Disadvantages:

  • Bob is a believer in TDD (Test Driven Development). This creates situations where the unit-test cases become complicated to right and maintain as he needs to check and see if all branches are being iterated or not.
  • The code prone to complications. What if you get one more enum condition for example "QUEUED" or "REQUEST_DROPPED" the list of conditions will keep on increasing and thus the headache.
  • Code has low reusability. Imagine Bob again wants to use the same conditions but except the ACCEPTED state. He would have to write all the conditions again.
  • Cyclomatic complexity will be high, so the code may not pass the quality thresholds defined by the customer or project architect.

Rule-based pattern to rescue

Formal Definition

Rules design pattern helps the developer to encapsulate each business rule in a separate object and decouple the definition of business rules from their processing. New rules can be added without the need to modify the rest of the application logic. ?????

Rule-based in Nutshell

For me personally rule based design pattern is an extension of the Factory pattern. The observation I did is that we compare the logic on a similar object (Request in our case) and create a response on the same basis. Instead of returning the response as a string what if we return an object and we can read the response from them?

The end goal we want to achieve should look something like this

No alt text provided for this image

The flow would look something like this

  1. The request-id is injected into the RequestAdapterclass which maps the status of request_id to the correct RequestHandler
  2. Now the correct RequestHanlder has been assigned it can return the status as per the methodology implemented

The snippets attached below will first implement the RequestFactory with its subclasses and would be utilized by the RequestAdapter in the further snippet

No alt text provided for this image

We are done with condition mapping now we need a class that acts as an adapted and helps us map the right object according to the conditions.

No alt text provided for this image

Advantages:

  • Rules can be arranged and used dynamically from modules inheriting the same parent class.
  • Adding new rules would be easier for modules.
  • Unit testing is easy. Each class can be tested independently without much fear of regressions

Disadvantages:

  • Not an obvious choice for novice developers.

Conclusion

People usually feel the implementation is code-heavy and takes a lot of time. The benefits of this pattern are usually seen in the long run when the backend code goes through iterative changes and the behavior changes as per the new policies.

Hamzah Jamal

Staff Engineer at TRACT | Ex - Tide| Morgan Stanley | Bank Of America

2 年

We at Tide use expression language library, while rules sit in a json/yaml file(s) There are times when you have to do attribute preprocessing, but by and large looks way cleaner.

Vinay Ag

Software Engineer III | Java 8 | Microservices | Spring boot | REST APIs |

2 年

Helpful

Abhinav Singh

Senior Data Engineer || Spark, Azure, Python, Databricks, Snowflake, SQL | Building robust, scalable data solutions to fuel business insights

2 年

Ken and Ryu ! My favourite characters.

Gaurav Sen

Founder, InterviewReady

2 年

Interesting story with Bob. This looks similar to the design pattern commonly known as "state pattern".

要查看或添加评论,请登录

Navjot Bansal的更多文章

社区洞察

其他会员也浏览了