2

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.

FrustratedWithFormsDesigner
  • 46,105
  • 7
  • 126
  • 176
Jordan Reiter
  • 623
  • 5
  • 13
  • 1
    It sounds like you're asking about Domain Specific Languages. http://en.wikipedia.org/wiki/Domain-specific_language Also: http://fmeyer.org/en/writing-a-DSL-with-python.html And: http://stackoverflow.com/a/142306/192801 And: http://www.slideshare.net/Siddhi/creating-domain-specific-languages-in-python – FrustratedWithFormsDesigner Apr 10 '12 at 20:16
  • I was just about to say that :) – Torbjørn Apr 10 '12 at 20:17
  • 2
    @FrustratedWithFormsDesigner: No, it sounds like he wants to get himself some headaches and in trouble. "The 100% configurable business logic overlord system". – Falcon Apr 10 '12 at 20:18
  • 1
    @Falcon: Ah, perhaps he wants an Entity-Attribute-Value system? http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model – FrustratedWithFormsDesigner Apr 10 '12 at 20:19
  • 2
    http://thedailywtf.com/Articles/The_Inner-Platform_Effect.aspx A cautionary tale. This road has been gone down by many, many people before you. It can be a positive thing, but look at all the links in the comments before embarking. – psr Apr 10 '12 at 20:51
  • And this article is also great: http://thedailywtf.com/Articles/The_Enterprise_Rules_Engine.aspx – Falcon Apr 10 '12 at 21:17
  • Okay, sounds like there's less of a headache down the road if I just go ahead and code each time. What I've settled on is creating a model called Rule that stores the name of a function to call on the object. That way I can associate rules dynamically but have the logic of those rules handled by a function. Code in pastebin: http://pastebin.com/BPwvJAsc – Jordan Reiter Apr 10 '12 at 23:12

2 Answers2

3

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.

Falcon
  • 19,248
  • 4
  • 78
  • 93
0

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

What would you like to do instead? The only options are to either use a Turing-complete language, which will be of approximately the same complexity as Python, or to use a simpler but less powerful language. The second option has been attempted many times, but invariably someone wants to write a rule that cannot be expressed in the rules language. You already have a fairly expressive language available that allows you to publish new rules with minimal effort. It will be hard to do much better.

kevin cline
  • 33,608
  • 3
  • 71
  • 142