If your system includes a big, odd calculation, you should think really hard prior to hand coding it. If there are a hundred rules or more and they fall into some kind of nice pattern, you can probably create a custom rules engine, save yourself a lot of time, while also providing a solution that is much easier to maintain over time. Custom rules engines are not just useful for large systems such as a rating engine for an insurance policy, or determining the credit score for a customer. They can save you a lot of effort even for smaller, complex tasks involving lots of similar rules.
Dulcian has been working on recruiting systems for the US Air Force for over a decade. There have been some interesting challenges over the years. One of the most interesting is known as “Grade Calculation.” This entails determining what rank someone is supposed to be assigned to when they enlist in the military. Applicants receive credit for all sorts of things including education, professional certifications, military experience, etc. The rules are a nightmare and there are a lot of them (265 currently).
Prior to Dulcian trying to code this, it had mostly been hand-coded and it was very difficult to do it perfectly every time.
The rules did not fit nicely into any of BRIM’s rule repositories. These were not really rules about “things” or the UI, they were rules about how to calculate a number. Since each rule was independent, it did not make sense to try to adapt the process engine in order to support these rules.
However, the rules were all pretty similar. There ended up being 8 different types. They all involved looking at some values or parameters in the database and calculating a value. These values would add up and allow us to assign a “grade” to the application.
We had two choices:
- We could either code it all by hand by trying to code each rule in a similar way in order to make the code readable and easy to maintain, or
- We could go to the next step and build a mini-repository and code generator to deal with the rules.
We have built a lot of code generators over the years, so a mini-generator seemed like a pretty good idea.
It turns out that the custom built rules repository worked out very well. We were able to get all of the rules into the repository. The repository approach meant that the rules could be easily reviewed by a functional expert. As rules changed, were revised, or were determined to be wrong in the first place, we were easily able to modify the rules. To help document the rules, each rule was tied to a source document rule (for example: “Table 2.5 Rule 35 Note 4”).
Since the package is only invoked once or twice per applicant, performance was never a huge issue. We were able to implement this as an interpreted (accessed at runtime) repository. The runtime “engine” consists of about 6000 lines of code. Part of the reason why it is so big is that it has to calculate lots of answers to questions that are not directly stored in the database, such as “Did the applicant ever have a break in service?.”
If all of the rules also had to be hand-coded, I suspect this would have ended up being a 20,000-30,000 line of code mini-project. Maintenance would have been an ongoing challenge.