Dynamic Business Logic – Adding Business Process Checks in Python

business-logicdomain-specific-languagespython

I'm wondering if there is a good extant pattern (language here is Python/Django but also interested on the more abstract level) for creating a business logic layer that can be created without coding.

For example, suppose that a house rental should only be available during a specific time. A coder might create the following class:

from bizlogic import rules, LogicRule
from orders.models import Order

class BeachHouseAvailable(LogicRule):

    def check(self, reservation):
        house = reservation.house_reserved
        if not (house.earliest_available < reservation.starts < house.latest_available )
            raise RuleViolationWhen("Beach house is available only between %s and %s" % (house.earliest_available, house.latest_available))
        return True

rules.add(Order, BeachHouseAvailable, name="BeachHouse Available")

This is fine, but I don't want to have to code something like this each time a new rule is needed.

I'd like to create something dynamic, ideally something that can be stored in a database.

The thing is, it would have to be flexible enough to encompass a wide variety of rules:

  • avoiding duplicates/overlaps (to continue the example "You already have a reservation for this time/location")
  • logic rules ("You can't rent a house to yourself", "This house is in a different place from your chosen destination")
  • sanity tests ("You've set a rental price that's 10x the normal rate. Are you sure this is the right price?"

Things like that.

Before I recreate the wheel, I'm wondering if there are already methods out there for doing something like this.

Best Answer

This is fine, but I don't want to have to code something like this each time a new rule is needed.

I'd like to create something dynamic, ideally something that can be stored in a database.

Well, judging from your requirements, you will have to code something. A new logic rule means a new implementation. How can you sanely solve that without logical code? If you have enough fields in a database for every possibility that would most probably lead to unmanageable complexity.

I think what you really want is easy deployment: New rules, probably customized, without the need to redeploy the whole system.

The thing is, it would have to be flexible enough to encompass a wide variety of rules [...]

Like I said above: It'll be damn hard to solve such problems solely by configurations if the use case is mildly complex.

I think what you want is extensibility, in addition to easy deployment. So it'd be probably best to create a DSL that suits your needs or embed a scripting language (which you probably don't need if you use Python). Then it's easy to create and deploy new rules. You then just configure the rules to use. The major challenge here is to design the interface to the "mother-system".

In many languages (including many compiled languages), this problem can be overcome with dependency injection and a microkernel pattern as well. Just collect all the rules from all the deployed rules libraries. This eliminates the need for scripting language support, if your business cases allow it (Field Technicians? Technical Support writes new rules while being at the customers site?).

Sure, you can go down that route, package sequences of business rules into workflows and so on, but that just leads to a special form of DSL. Some people call that business process modelling and I have yet to see a system that employs that kind of technology successfully.

P.S.

Advice: And please don't put your rules-files into a blob in a database.