We are trying to build a system that describes pricing rules for a set of products. After thinking about it for a while we have decided to use a table driven approach for capturing business rules describing the pricng structure. The columns capture the various attributes of the products/order form such as the territory it's sold in, the currency of the order, etc. The results/actions for each rule capture the prices. We choose to implement it this way for precisely the reason mentioned in the article - we want our end users to maintain the rules.
I have built systems like this (ones that worked, not just the anti-pattern described in my other comment). One caveat with EVERY “end users maintain this” system is that workflow rules, tables, DSLs, and everything else they “maintain” is CODE. It may not look like code, but if it drives the behaviour of the system, is code.
I take the view that if it walks like code and talks like code, it must be subject to the same rules as code. It must be checked into version control where it can be diffed and reverted. It must be pushed through staging and production. It must be testable, preferably with some kind of declarative tests.
In one system, we built the DSL for rules AND a DSL for declaring test cases so the analysts could write new rules and write tests for them.
You may have the same approach, or not as you deem appropriate.
Boy have I been bitten by that one before. I've learned after some time that punting the logic into customer-controllable data doesn't absolve it of all the problems that traditional code has.
In one system, we built the DSL for rules AND a DSL for declaring test cases so the analysts could write new rules and write tests for them.
Can you elaborate on how your DSL looks? How does one structure it to be powerful enough to encapsulate logic and simple enough for analysts to use?
Is it just simplified mathematical expressions? Or something more elaborate?
> One caveat with EVERY “end users maintain this” system is that workflow rules, tables, DSLs, and everything else they “maintain” is CODE. It may not look like code, but if it drives the behaviour of the system, is code.
In some ways the problem is much worse than for plain old code written by plain old programmers. Once a problem has been analyzed and the structure of its solution has crystalized, table-driven code can often be the right way to factor out the messy ad-hoc business requirements--there's a cool war story about that in Programming Pearls. But just throwing tables at everything for the business analysts to sort out is almost certain to lead to a combinatorially explosive mess of case analyses that's wholly unmaintainable. As you'd know if you've dealt with end-user programming, whether in the form of tables or visual scripting, non-programmer power users are perfectly willing to crank out reams upon reams of case analysis code when left to their own devices.
I think the argument is that the end users wouldn't be able to manipulate the table in ways other than flipping bits, and that the system should be able to support any combination of bits.
In reality (and I think this is your point) the consequence is that just because a system can support a particular combination doesn't mean it makes any sense for the problem domain. Therefore by exposing this to users without tests, they can screw themselves over, even if the system continues to "work."
Fully agree. The rules have to be versioned and validated. In fact in our use case we have to go a step further and have another dimension to support validation - the notion of the phase/stage the rules are in: work-in-progress rules vs activated rules.