Well-written multitier applications consist of multiple layers. The most widespread three-tier architecture divides our code into a presentation, business and data access tiers. Like it or not, but the business layer is where we, developers, spend the most time on a daily basis. This is the place where all processes and decisions our application depends on take place. Therefore, requirements for the business layer change more often than in any other layer. What hurts us, developers, most is that with every change, even the smallest ones, we need to recompile and rebuild our app. It usually takes a piece of the valuable time that we could use for more interesting things. What if we could move a business logic out of our code and let non-technician people change it?
In this article, we will show how to move a business logic out of our code using a business rules engine called Hyperon. Firstly, we will create a simple Spring boot application that shows which Train ticket should be presented based on input data. Whole business logic will be placed inside the app in its code. Secondly, we will move that logic out in a form of decision tables using the Hyperon engine. Lastly, we will discuss the advantages and disadvantages of the decision tables and rules engine.
What Problem We Are Trying to Solve
Let’s imagine an application to sell Train tickets. Firstly, we must select all
necessary information such as our destination and place from which we start our journey, seat class, and how many tickets do we need. After that, the app usually shows us a list of matching tickets with their prices.
Let’s start with an easy example. We would like to show a customer a ticket based on the selected seat class. Here’s how it can be controlled in a simple switch statement in our code:
Nothing fancy here, it’s pretty straightforward. What if we would like to return different tickets based on seat class and travel distance? Here’s how it could look in our code:
Business logic is still pretty straightforward, but the number of lines in our code noticeably increased and it’s got pretty uglier too. I think we all know where we’re heading to if we’ll increase the number of input parameters that our logic depends on.
Consequently, any change in business requirements is also pretty hard and time-consuming in that approach. First, we need to search for a class that’s responsible for a specific part of business logic and modify it. Then we need to rebuild our app and propagate it to all environments (test, QA, pre-prod, etc). With that in mind, a small change can take a few weeks to land in the production environment.
What if we could change any business requirement and see it in the production environment in a matter of a few minutes?
What Is The Hyperon
Hyperon is a tool for managing business rules. It consists of 3 modules:
- Hyperon Studio – a standalone GUI to create and modify
- Hyperon Runtime – a small Jar to include as a dependency in your application. It provides useful classes that you can use to ask for any business rule created in the Hyperon Studio.
- Hyperon Runtime Rest – a standalone REST version of the Hyperon Runtime.
The main advantage of Hyperon is its performance. It’s around 62 times faster than Drools, the most popular business rules engine. You can check that on your computer, a public repo with all the necessary code and additional readme file is available here: https://github.com/hyperon-io/hyperon_vs_drools
However, the most important Hyperon feature in our case is a runtime modification. What that means is we don’t have to shut down the system when we want to change any business rule and see that change in the production environment.
One of the core concepts in Hyperon is a decision table. It is used to specify which actions to perform depending on given conditions. To put it another way, a decision table is a graphical representation of a decision tree or a series of if..else statements in every programming language.
Let’s see how can we use decision tables to move our business logic out of our code using Hyperon.
Problem solution in Hyperon
Let’s see how our first ticket train application requirement looks in the Hyperon Studio:
It’s exactly the same first switch statement in a form of a business rule called a parameter. Input data is presented in an IN section. The OUT section is where we put data we want to return as a result. Ok, but how can we get the result from our code? Here’s how:
The HyperonEngine class is the main facade you work with from the Hyperon Runtime module. You can read more about it here: (https://www.hyperon.io/tutorial/getting-parameter-value). We need to specify the unique code of the parameter (business rule) we want to invoke and pass an input value in a form of a HyperonContext class (https://www.hyperon.io/tutorial/hyperon-concepts-context). For now, we can think of it as a key-value map. We can use keys and corresponding values as a value source in parameters.
Let’s see how the second requirement looks in the Hyperon Studio:
The only difference is a new distance input level. Fetching the result in our code looks almost identical as in the previous version:
As we see, the code complexity is pretty much the same which is not the case in the Hyperon-less approach. What’s more, the decision table readability is far better than a big if..else block in Java. Not only an
IT guy but also a business person knows what will be returned from a given
business rule by looking in the parameter definition in the Hyperon Studio.
Let’s try something harder. What if we would like to return different tickets based on selected seat class, travel distance, and optional passenger discount? In the Java approach, we would probably need to add another
if..else block in the main switch statement. On the other hand, in the Hyperon Studio we need to add another input level and corresponding data:
In Hyperon, the value source for each input level can be from one of three different places:
- a value from the context
- other parameters
- other functions
We haven’t talked about functions in Hyperon yet. Business Rules are a powerful concept, but like any other tool, they have limits. That’s why the Hyperon Studio allows writing small Groovy functions. With the combination of parameters and functions, even the most complicated business rule can be designed in Hyperon.
Here’s how the function specified in the value source looks like:
It’s a simple function that calculates the difference between the current date and the birthday variable from the context.
The only change we need to do in our code is to add another key-value pair in the context, that is passed together with parameter code to invoke:
What if after a while a discount algorithm must be changed? No problem, we change the function in the Hyperon Studio, we don’t touch our Java code at all. This is the beauty of the Hyperon approach.
Let’s change our requirements for the last time. Now, we would like to return not only a ticket code but also the size of an optional discount for a given ticket. Here’s how it could look in the Hyperon Studio:
We just added a new OUT column to store the size of the discount. The biggest difference here comparing to the previous parameters are function references in the matrix data. In general, you can store data in the matrix in 3 different ways:
- parameter result
- function result
It’s a practically identical situation as in the value source field in input levels.
What about Java code? Let’s find out:
The only difference here is how we handle the invocation result.
Hyperon benefits and drawbacks
According to the examples in the previous chapter, is Hyperon a perfect business rules engine without any drawbacks? Of course not, such system does not exist. The biggest drawback is the learning curve of the new tool you are going to use in your application. What’s more, Hyperon might be overkill for applications with pretty simple business logic. Lastly, Hyperon won’t be the best fit in systems, where business rules hardly ever change.
However, the large number of benefits outweigh that drawback the longer you and your business use Hyperon. The decrease in the development cost, much shorter time to market are just a few examples we showed in this article. You can read more about it here (https://www.hyperon.io/why/benefits).
In this article, we discussed Hyperon, the business rules engine. We talked about decision tables and business rules in general. We showed how they work in a train ticket application. We presented a Java-only approach and an increase in the code complexity with any additional business requirements. Then, we showed the same scenario in the Hyperon environment. Finally, we discussed some of the Hyperon’s benefits and drawbacks.
The examples from this article can be found in our Github: (https://github.com/hyperon-io/train-ticket-article-app). You can find there also a few demo apps demonstrating the power of Hyperon in real-world scenarios.
Visit this site: https://www.hyperon.io/lp/business-rules-engine to read more about business rules in Hyperon and watch a short video showing a quick business rule change on a live application.