问题
I'm new to drools and trying to use guvnor to build a simple Framingham score calculator.
An example is: lets say you are a 30yo male, you start with -9 points. If your total cholesterol is 180, add 4 points, if your a smoker add 8 points, if your HDL cholesterol is over 60, subtract 1 point, and if your blood pressure is 135 then add 1 point. Giving you a result of +3.
The tables on the score sheet seem like a great scenario for a drools decision table(s).
I'm having trouble figuring out how to add the individual score numbers together.
I stared by creating a new "FraminghamScore" fact for my result column, but then I need to add these facts together.
I tried to join all the tables into 1, but that gets complex and redundant real quick.
It looks like if I were to create my FraminghamScore in java, I could have a incrementValue(int) method that I could call, but then I couldn't figure out how to pass a number to it.
回答1:
In case you decide to refactor your app to use drools instead, and if someone else is looking for a solution to a similar problem, here are my two cents of drools knowledge.
Your facts could be something like this
// Fact for the scoring
class FraminghamScore {
private int total;
public void increment( int value ) { total += value; }
public int getTotal() { return total; }
}
// Fact for the subject
class Person {
public enum Gender{ MALE, FEMALE };
private Gender gender;
private int age;
private int cholesterol;
private boolean smoker;
// Rest of the fields + getter/setters as needed
}
Your decision tables would be something like below. As I see it, there will be some duplication in age checking for example, I can't think of a way to get rid off those.
Condition | Condition | Action
-----------------------------------------------------------------------------------
$p : Person() |
$s : FraminghamScore() |
-----------------------------------------------------------------------------------
p.gender | $param | s.increment($param);
| | update(s);
-----------------------------------------------------------------------------------
MALE | p.age >= 20 && p.age <= 34 | -9
MALE | p.age >= 35 && p.age <= 39 | -5
-- Rest of the age groups + same for females
Condition | Condition | Action
-----------------------------------------------------------------------------------
$p : Person() |
$s : FraminghamScore() |
-----------------------------------------------------------------------------------
p.gender | p.smoker | s.increment($param);
| | update(s);
-----------------------------------------------------------------------------------
MALE | true | -9
MALE | false | -5
And so forth.
Now looking at the tables, I see that there will be awfully lot of duplication with the age checking. Can't think of a better way at the moment, though. Hope this helps at least a bit.
EDIT
You can have the FraminhamScore fact only to hold the amount of point per each rule instead of summing them together there. With this option, you'd add a score fact to working memory per rule and use query to fetch them in the end and then do math. This might keep your decision tables cleaner.
来源:https://stackoverflow.com/questions/13096040/how-to-create-a-score-from-several-drools-decision-tables