Wayne Molina
Wayne Molina

Reputation: 19596

Architecting a solution that could have potentially infinite classes with custom business rules

I'm working on a "smart" issue tracking application that needs to determine if a particular issue can be submitted in a ticket before actually allowing submission.

The design issue I'm running into at present is the fact there can me many different types of "submittable" issues, each with its own unique business logic that determines if the issue can actually be submitted. From my design notes I have the following conditions:

  1. Supports multiple issues (unknown number, in theory could be infinite)
  2. Each issue is directly related to a specific shipment (i.e. user selects their issue, and then is prompted to choose/enter the shipment they have the issue with)
  3. Each issue has its own custom validations/business rules (data is provided by the shipment) that determines if the issue can proceed. Examples would be:
    • If the issue is a Damage Claim, the shipment has to have been picked up within 60 days.
    • If the issue is a Cancellation/Refund, the shipment status can't be delivered.

The idea is almost like an insurance processing application but all the information is already provided by asking the shipment, instead of having to rely on user input (e.g. I don't need to ask when the shipment was sent, I can ask the shipment object for it's PickupDate), and there are only two outcomes: 1) The issue can have a case opened, or 2) No, the issue cannot have a case (aka the "tough luck" option). On the architectural end, even if I'm using some kind of STRATEGY pattern that can support multiple types of issues, it would require a custom class to be created for every derived type of issue. For instance I would need a DamageClaimIssue and a CancellationRequestIssue and who knows what else; this seems cumbersome on the developer side since new types can be added almost at a whim and would require a developer to spin up a new derived class and implement the validation logic, and then recompile and redeploy.

Is using Strategy the best way to handle an issue like this, or am I overlooking something? In theory I'd like to make the architecture generic enough to accommodate different issues (I know there will be more than 2-3, I just don't know what they will be exactly), but I don't want to go the route of having some monolithic workflow engine using XML or similar that lets things get defined on-the-fly with dynamic logic. I have to use standard .NET 3.5 libraries (i.e. nothing like WCF or Workflow Foundation).

Any suggestions or pointers to set me in the right direction?

Upvotes: 2

Views: 133

Answers (3)

Ravi Bhatt
Ravi Bhatt

Reputation: 3163

I would suggest using a Business Rule Engine System like drools in Java.

http://droolsdotnet.codehaus.org/

Upvotes: 0

Adrian K
Adrian K

Reputation: 10215

I think Doc's answer is good, although I would investigate rules engines first as it sounds like the sort of thing you need. Why re-invent the wheel? You should be able to find open source and paid versions.

We used a .Net port of an IBM tool called iLog recently; I can;t say it was painless but it did the job. From memory users could edit rules in Excel and import into the app.

The only other bit of advice I have to to keep things as simple as possible. It's likely that somewhere there will be an elegant "mess" of rules, etc (which in themselves will be complex) make sure you keep everything else as simple as you can - you don't want a complex / messy deployment / upgrade / versioning situation.

Upvotes: 0

Doc Brown
Doc Brown

Reputation: 20044

The first thing to ask here is: who shall be responsible for defining new types of issues in your system?

When I understood you correctly, it should be a user (perhaps not every user, but a "power user") and not the developers of your system. So you need a generic issue type, or a handful of issue types which should not be too specific and can be further refined by parameters given by the user. Concerning validations/business rules: you can try to define a DSL for that, in which a user can define these rules by himself. Rules defined in this DSL can be stored as part of the type definition, perhaps in a database, so DSL code must be interpreted by your engine when the validation applies.

Of course, the hard part is to define a good DSL for your purpose, easy enough to be understood by users and flexible enough to let them describe every rule they need.

Upvotes: 2

Related Questions