I was going through Drools documentation and found it is not doing anything interesting / solving any problems (May be I'm wrong).
In drools we specify the business rules (in .drl file) as, for example,
when "type = jewellery" then setDiscount(25%)
when "type = KidDress" then setDiscount(30%)
What is the difference between the above vs using database?
I can ALWAYS expose custom API's from which business rules can be specified and I can directly store it in RDBMS. Formally if required, I can build a sample UI (in 1-2 days) which integrates with exposed APIs. This will also allow business people's to easily add/update/delete rules If I expose CRUD operations.
For something as simple as I explained, what problem is Drools solving? I cannot find in any documentation from g-search / in official documentation.
Can someone help here?
In contrast to Karol's answer, I also used Drools but I had an excellent experience with them. The use cases in the documentation are intentionally simplified, but Drools can also handle much more complex use cases more efficiently than a database. I know this for a fact, because a service that I maintained with ~ 1.4 million rules was converted to using a database (using the same arguments you presented). It went from averaging 30-100 ms to respond to a query, to taking 750ms to over 2 minutes to respond (how much longer I do not know because we timed out our queries after 2 minutes.)
The reason for this was that Drools allowed us to implement "fall through" logic. In this case, my 1.4 million rules were determining if a hospital patient would need authorization from their insurance to have a procedure done at a hospital. The rules ranged from very general to very specific; if two rules matched the input data, we favored the more specific rule. Special use cases applied if a specific hospital or hospital+insurance combination had a custom rule. We passed all the data we knew about the patient in, their entire medical history, and a ton of information about their insurance, and then the rules decided on the answer.
Imagine this intentionally simplified scenario:
rule "Car"
when
Car() // very simple, I have a car
then
setPrice(100)
end
rule "Red Car"
when
Car( color == "red" ) // I have a red car
then
setPrice(75)
end
rule "4-door Car"
when
Car( doors == 4 ) // I have a 4-door car
then
setPrice(200)
end
rule "Red Sedan"
when
Car( color == "red", model == "sedan") // I have a red sedan
then
setPrice(500)
end
rule "Blue 4-Door Discount"
when
Car( doors == 4, color == "blue") // I have a blue 4-door car
then
setPrice(150)
end
Now we start playing in different configurations of Car. A yellow car, 2-door sports car only matches the first rule and the price is 100. A red 4-door car matches two rules; is the price 75 or 200? Depends on how you've written your rules and what "set price" does; likely in the rules I've written here the price is 200. A blue sedan? 100. And so on.
If we converted this into a database table (for simplicity, a single table Car with columns 'color', 'model', and 'doors'), what would that query look like? (I don't actually know I didn't manage to write a query that would suffice; I'm also not a DBA.)
I could come up with a whole set of examples where a database-based solution would be less performant, or not recommended at all. For example, I once implemented a psuedo-BFS algorithm using rules to figure out an optimal upgrade path from an arbitary hardware configuration to the latest supported configuration. (Each version could only be upgraded to distinct other versions, so we needed to figure out the fastest path from a given version to a target version, if possible.) Could this have been done in a database? Possibly, but it's not the sort of thing a relational db would be good for. What about code? Sure, but now you'd have to manage your list of what-can-upgrade-to-what in code.
For extremely simple rule sets where each rule is completely exclusive and covers all use cases? Sure a database might be more performant. Real world situations, however, would either require overly complex queries, or might not be appropriate at all.
And decision tables? Avoid them at all costs. They are slow to load, slow to execute, hog way more memory than they need, have undocumented limitations that you'll run into if trying to use them at scale, and debugging them is a pain.
The two main points:
In theory Drools rules are written in a way that can be easier to understood by non-technical people like business analysts.
If decision logic is stored in one place e.g. as a Decision Table it might be easier to manage. This is sometimes handy if you have a more complex calculation with a lot of variables like credit check criteria.
In practice in all the projects that I worked on with Drools the developers had to write custom functions that were called from DRL file to handle more complex logic. This negated above benefits and made the solution significantly harder to manage because logic was shared between normal code and DRL files.
I had bad experience when Drools and similar tools. I'd not recommend for simple use-cases.
Related
Suppose that I have a game that has fairly simple rules, but may have any number of rules modifiers. (For boardgames, the classical example would be Cosmic Encounter). The base rules are easy to program, but you cannot write all the conditional logic at the time. For example, if your game has 100 possible modifiers (but say only 5 are active at a time) that's 100 choose 5 possibilities and you can't enumerate them manually. So how is this done?
(This could also be for any business logic rules engine, but games are where I seem to encounter this more often).
I would think you might be able to do this by having "state" objects and then passing them through a series of modifier objects, but I'm not sure this is the right way of doing it. What is the technique / style for this? What are some good primers/examples?
(I can program well enough, but with my EE degree have only whatever theory I've picked up on the job....).
We have a requirement such that Users need to be presented different facts based on some constraints.
Similar Hypothetical Example
If User belongs to Australia and earns more than 10k$ then show XYZ view of data/facts
If User belongs to USA and earns less than 5k$ then show ABC view of data/facts
...
...
Now we can either,
keep this mapping in the user model and have these business rules in the code
or
we can pull these rules out into a JSON or a DSL where we can simply change the rule without having to deploy the code for every single change.
We dont know how frequently these rules will change.
I have read arguments for and against the idea of a custom mini rule engine.
Arguments for:
Every small change will not require a deployment
All the rules related to this specific functionality are at one place (probably) making it easier to get an overview
Arguments against:
(Martin Fowler article) It will become difficult to reason about your code
Anemic Data model anti-pattern
Over time it will be difficult to manage these rules
Conflicts between rules or the chance of some facts not belonging to any of
In general it depends on your use case. Looking at the examples you have provided it looks like an excellent application of a rules engine. By externalising that logic you'll make your application more declarative, easier to maintain, and will deliver value to your users faster.
In your case this is the key statement:
We dont know how frequently these rules will change.
That suggests that you really need to externalize that logic either to a rules engine or a DSL of your choice. If you don't you'll be signing up to deploy new code every time those rules do change.
Your examples as written are pretty classic examples of ProductionRules
https://martinfowler.com/dslCatalog/productionRule.html
https://en.wikipedia.org/wiki/Production_system_(computer_science)
There are many good open source and commercial rules engines available. I'd consider those before creating a custom DSL. The logic you've written matches very well with those systems.
Some of the technical downsides of rules engines and DSLs are:
Rules systems can be difficult to test
You have to carefully design the inputs and outputs to your rules
You'll need to understand, document, and integrate another tool or custom DSL parser
Building rules is a different mental model than some developers are used to and it can take time to do it well
There is nothing wrong having business logic abstracted. And declarative rules seem appropriate in your scenario. One should be able to extract a - human readable - report, showing the business logic, the rules applied.
So the first stage would be the requirements, what you would like as product.
This can become extra code/modeling without impeding on the existent code base.
Do not start in the wild: do not search a solution library, when the problem and solution are unclear. Often a "solution framework" is applied, and the problem modeled after that. With much boiler plate code and not exactly matching what you actually would want.
At this stage you probably could make a simple prototype of a do-it-yourself rule engine. Maybe even make a fast and rough prototype. Then look for existing rule engines, and make prototypes. Preferably not on your application, but using Test-Driven-Development in unittests.
A bad idea is to immediately leave the rules definition maintenance to the end admin users. Such functionality has implications: missing test staging, working on the production system, versioning, technical qualifications of end users like big integrative picture.
As a last remark: this might have been something for the Software Engineering forum.
My current application has a number of rules in the form of if-else conditional statements that work on some parameters to either modify some set of variables or set/unset other variables. Due the increasing clients that we are having, the application code is now getting cluttered with these if-else rules. Also, these rules are not static they change quite frequently tweaked, some are made to expire other's activated etc. I have seen that drools etc based on JSR094 provide this functionality to separate logic/rules from application source code.
My requirement is not so complex, I don't need complex rule visualization software, editing UI, etc. but definitely dynamic(modifications/editable rules), also my requirement requires low latency as it processes some 100s of million requests a day.
Any ideas of a light weight implementation to solve this as I feel drools is overkill?
My platform for development is Java.
Example rule:
if ( age > 15 && item belongs_to(footwear) || using(mobile_device) )
discount = 2%
I strongly suggest you use a proper rule engine, drools, flexrule... If you do not like using those solution, you always can find some expression evaluation libraries that let you to parse and execution a string based expression.
The description may sound like just a bunch of words so here is a more detailed explanation. I have a User object which is mapped to database table.
I want users to be in different roles. There will be a bunch of those - and they technically will be the same users in same table but to them will apply different roles. Say user in role A will have to have two fields as required, and will have to have certain restrictions to the length and contents on his password, as well as the time expiration of his password, etc.
While I can hardcore those rules I am very interested to find out of there is an other way to define the rules and may be store in database so it's easier to load/apply and the main idea - to change and update them -- without redeploying the codebase.
Technically the stupidest and straightforward solution is to implement class, serialized, store in db, then load, deserialze, call methods on it which will execute rules. The problem is in changes to the ruleset ( read "interface" of the rule class ) and that generally solution sounds like a hack.
Anytihing else? Any frameworks? Other approaches?
UPDATE: probably was not clear. say, I have class User.java
I need to define different rules say:
1. do we need to verify length of password, and what should it be?
2. do we need to require some properties to be required?
3. do we need to track login attempts for this user?
4. if we do track, how many login attempts allowed?
5. do we expire password?
6. if we do, then in how many days? or months? or weeks?
7. ...
and so on and so on.
so questions ARE.
- how do I define those rules and operate on User object WITHOUT modifying and redeploying code base?
- how do I store those set of rules?
Drools, jBPM, etc. do not seem like a fit for that task. But any advice would help!
JRuleengine is good I heard, sometime back I planned to use it for similar application.
There are many other Rule Engines though.
Well there are some good rules engines out there include jrules, drools I think is popular too. One thing to keep in mind is the relationship between a rule and the data it examines. After all you can have the rules in a word document, but when they execute they need examine data, and that is also a factor in choosing a rule engine or architecture. generally its if (a > b) then do y. Means you need to examine a and b in the rule execution. That is the real issue is how to get the parameters into the rule and engine.
First of all, I have a very superficial knowledge of SAP. According to my understanding, they provide a number of industry specific solutions. The concept seems very interesting and I work on something similar for banking industry. The biggest challenge we face is how to adapt our products for different clients. Many concepts are quite similar across enterprises, but there are always some client-specific requirements that have to be resolved through configuration and customization. Often this requires reimplementing and developing customer specific features.
I wonder how efficient in this sense SAP products are. How much effort has to be spent in order to adapt the product so it satisfies specific customer needs? What are the mechanisms used (configuration, programming etc)? How would this compare to developing custom solution from scratch? Are they capable of leveraging and promoting best practices?
Disclaimer: I'm talking about the ABAP-based part of SAP software only.
Disclaimer 2, ref PATRYs response: HR is quite a bit different from the rest of the SAP/ABAP world. I do feel rather competent as a general-purpose ABAP developer, but HR programming is so far off my personal beacon that I've never even tried to understand what they're doing there. %-|
According to my understanding, they provide a number of industry specific solutions.
They do - but be careful when comparing your own programs to these solutions. For example, IS-H (SAP for Healthcare) started off as an extension of the SD (Sales & Distribution) system, but has become very much more since then. While you could technically use all of the techniques they use for their IS, you really should ask a competent technical consultant before you do - there are an awful lot of pits to avoid.
The concept seems very interesting and I work on something similar for banking industry.
Note that a SAP for Banking IS already exists. See here for the documentation.
The biggest challenge we face is how to adapt our products for different clients.
I'd rather rephrase this as "The biggest challenge is to know where the product is likely to be adapted and to structurally prepare the product for adaption." The adaption techniques are well researched and easily employed once you know where the customer is likely to deviate from your idea of the perfect solution.
How much effort has to be spent in
order to adapt the product so it
satisfies specific customer needs?
That obviously depends on the deviation of the customer's needs from the standard path - but that won't help you. With a SAP-based system, you always have three choices. You can try to customize the system within its limits. Customizing basically means tweaking settings (think configuration tables, tens of thousands of them) and adding stuff (program fragments, forms, ...) in places that are intended to do so. Technology - see below.
Sometimes customizing isn't enough - you can develop things additionally. A very frequent requirement is some additional reporting tool. With the SAP system, you get the entire development environment delivered - the very same tools that all the standard applications were written with. Your programs can peacefully coexist with the standard programs and even use common routines and data. Of course you can really screw things up, but show me a real programming environment where you can't.
The third option is to modify the standard implementations. Modifications are like a really sharp two-edged kitchen knife - you might be able to cook really cool things in half of the time required by others, but you might hurt yourself really badly if you don't know what you're doing. Even if you don't really intend to modify the standard programs, it's very comforting to know that you could and that you have full access to the coding.
(Note that this is about the application programs only - you have no chance whatsoever to tweak the kernel, but fortunately, that's rarely necessary.)
What are the mechanisms used (configuration, programming etc)?
Configurations is mostly about configuration tables with more or less sophisticated dialog applications. For the programming part of customizing, there's the extension framework - see http://help.sap.com/saphelp_nw70ehp1/helpdata/en/35/f9934257a5c86ae10000000a155106/frameset.htm for details. It's basically a controlled version of dependency injection. As a solution developer, you have to anticipate the extension points, define the interface that has to be implemented by the customer code and then embed the call in your code. As a project developer, you have to create an implementation that adheres to the interface and activate it. The basic runtime system takes care of glueing the two programs together, you don't have to worry about that.
How would this compare to developing custom solution from scratch?
IMHO this depends on how much of the solution is the same for all customers and how much of it has to be adapted. It's really hard to be more specific without knowing more about what you want to do.
I can only speak for the Human Resource component, but this is a component where there is a lot of difference between customers, based on a common need.
First, most of the time you set the value for a group, and then associate the object (person, location...) with a group depending on one or two values. This is akin to an indirection, and allow for great flexibility, as you can change the association for a given location without changing the others. in a few case, there is a 3 level indirection...
Second, there is a lot of customization that is nearly programming. Payroll or administrative operations are first class example of this. In the later cas, you get a table with the operation (hiring for example), the event (creation, modification...) a code for the action (I for test, F to call a function, O for a standard operation) and a text field describing the parameters of a function ("C P0001, begda, endda" to create a structure P001 with default values).
Third, you can also use such a table to indicate a function or class (ABAP-OO), that will be dynamically called. You get a developer to create this function or class, and then indicate this in the table. This is a method to replace a functionality by another one, or extend it. This is used extensively in the ESS/MSS.
Last, there is also extension point or file that you can modify. this is nearly the same as the previous one, except that you don't need to indicate the change : the file is always used (ZXPADU01/02 for HR modification of infotype)
hope this help
Guillaume PATRY