Author: Little Fu Ge
Warm spring breeze blowing head on, peach blossom more open
Small Fu Ge | bugstack. Cn precipitation, share, grow, and focus on the original project cases, to share knowledge in the most easy to learn programming way, let oneself and others to learn something. Projects completed so far are; Netty4.x practical case, implementing JVM with Java, full-link monitoring based on JavaAgent, handwritten RPC framework, architectural design case, source analysis, etc. You use the sword 🗡, I use the knife 🔪, good code is very burning, hope you don’t stingy move!
One, foreword
Have you ever seen code like this? How about something like that? Well, congratulations on being treated gently by the world!
If else, it’s not really a bad keyword, it’s just somebody broke it. Especially after receiving the product demand as follows;
The date of | demand | The degree of emergency | Programmer (VOICE) |
---|---|---|---|
Monday morning | Ape brother, the boss said to do some marketing pull quantity, give boys and girls to send different coupons, promote consumption. | It’s urgent. I need it after work | Okay, it’s not that hard. Add a judgment and go online |
Tuesday afternoon | Dude, we’ve been great since we got online. Let us according to the young, middle-aged, adult, different age plus judgment, accurate stimulation of consumption. | It’s super urgent. I need it tomorrow | It’s not hard. Just add it |
Wednesday evening | Hey, little brother! To sleep! The boss said that our activity was very successful, can we subdivide the single, married and children into different judgments? This is more incentive for users to spend. | Thief emergency, online asap. | Be aware ofifelse More and more |
Thursday. Early morning | A: wow! You guys are so good. You got there so fast. Hee hee! I have a small request, we need to adjust the age group, because now the students of the Student Affairs Office are early, it is easier for those who have a date to buy something. Change the value! Hard work! | Boss, waiting! | A lot of values to change, oops! So muchifelse the |
Friday. Midnight | Say hello! Baba, broken, how to send the wrong coupon, a customer complained, a lot of girls to complain. Look at that. The boss, he… | (a sweat), ah, the value of the wrong position! | After all, a person carried all |
Have you ever come across such a scenario, so is the product for you to go to the ditch, or you take the project to the ditch. You might think, I can’t help it if it’s so urgent. In fact, not only do you have no way, it is to win the market, so that everyone is in a hurry. Only reasonable evaluation, paving, setting up, will continue to meet the business needs, product form changes. Otherwise the road is getting harder and harder!
Second, the scene
Scenarios like the one mentioned above are often encountered in our actual development. Especially in some; Marketing, risk control, crowd, etc., all kinds of user information decision tree relationship, will appear such business logic. And for some larger scenarios, you definitely won’t hardcode if else directly because it’s too difficult to maintain. Unless, of course, you just write it once and use it once.
Next, we will transform the above scenario into a tree structure diagram, which in turn reflects the overall picture of this requirement, as follows;
- From the figure above, we can see that the decision flow of the product is a tree after the requirements are put together for a week. Each of these different factors can lead to different results.
- And if the whole content of the product is handed to you from a little bit to a whole package, you’re going to have a different r&d design. Of course, there are also the same, because there are some very far-sighted programmers, they step on the pit all the year round! And this same high design, is stepping on the experience of stepping out of the pit.
- So, in addition to
if else
What other solutions can you think of in your own tech stack? Next, we’ll write out two implementations for comparison.
If, else encoding
@Test
public void test_ifelse(a) {
Result result = null;
if ("Male".equals(policy.getSex())) {
if (policy.getAge() < 18) {
if (policy.getUserSingle()) {
result = Result.buildResult("A"."A red");
} else {
result = Result.buildResult("B"."Red" B"); }}else if (policy.getAge() >= 18 && policy.getAge() <= 30) {
if (policy.getUserMarry()) {
result = Result.buildResult("C"."Red C");
} else {
result = Result.buildResult("D".Red "D"); }}else if (policy.getAge() > 30) {
if (policy.getUserParenting()) {
result = Result.buildResult("E"."E" red);
} else {
result = Result.buildResult("F".Red "F"); }}}else if ("Female".equals(policy.getSex())) {
if (policy.getAge() < 18) {
if (policy.getUserSingle()) {
result = Result.buildResult("A".A "yellow");
} else {
result = Result.buildResult("B"."Yellow" B"); }}else if (policy.getAge() >= 18 && policy.getAge() <= 30) {
if (policy.getUserMarry()) {
result = Result.buildResult("C"."Yellow C");
} else {
result = Result.buildResult("D"."Yellow D"); }}else if (policy.getAge() > 30) {
if (policy.getUserParenting()) {
result = Result.buildResult("E".Yellow "E");
} else {
result = Result.buildResult("F"."Yellow F");
}
}
}
System.out.println("Decision result (IfElse) :" + result);
}
Copy the code
- That goes without saying, as long as it does
if else
Write out or no problem, but write wrong is not necessarily good, after all, a layer of a layer. That’s a small amount!
Rule engine Drools
The simple way to think about a rules engine is to separate out the parts of your business logic that are changing the behavior rules and processes. To a separate rules engine for processing. In the end, you just need to provide the configuration and input parameters by convention to achieve the result of the rule execution.
Drools (JBoss Rules) is an open source business Rules engine that is easy to access enterprise policies, easy to adjust, and easy to manage. It is fast and efficient and complies with industry standards. It allows business analysts or reviewers to easily view business rules to verify that the coded rules enforce the required business rules.
He slapped her and asked why. Ok, let’s do the above code with Drools and explain it later.
1. Configure the environment
- jdk1.8.0
- idea + maven3.x
- Drools 7.32.0. The Final
- Case source code download,Bugstack wormhole stackReply:
The source code for
- Visual flow chart solution; flowdiagram.itstack.org
2. Engineering structure
itstack-demo-drools-02└ ─ ─ the SRC ├ ─ ─ the main │ ├ ─ ─ Java │ │ └ ─ ─ org. Itstack. The demo │ │ ├ ─ ─ model │ │ │ └ ─ ─ the Policy. The Java │ │ └ ─ ─ Result. Java │ ├ ─ ─ Resources │ │ ├ ─ ─ meta-inf │ │ │ └ ─ ─ kmodule. XML │ │ └ ─ ─ rules │ │ └ ─ ─ tree. DRL │ └ ─ ─ webapp │ └ ─ ─ index. The HTML └ ─ ─ the test └─ Java sci-imp ─ org.sci-imp. Sci-impCopy the code
- The code in the case can be obtained by following the public account: BugStack wormhole stack, reply keyword **< get source code >**
- So that’s what we’re talking about
Drools
The basic engineering of the rule engine, the way the rule engine is used is not complicated, as long as it is set up in accordance with the convention.
3. Code explanation
Policy.java & defines decision attributes, which are also Fact objects
public class Policy {
private String sex; / / gender; Male and female
private Integer age; / / age
private Boolean userSingle; / / single; Yes/no
private Boolean userMarry; / / to get married; Yes/no
private Boolean userParenting; / / parenting; Yes/no. get/set }Copy the code
Result.java & defines the Result output
public class Result {
private String code;
private String info;
}
Copy the code
Meta-inf /kmodule.xml & configuration file
<?xml version="1.0" encoding="utf-8" ? >
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="rules">
<ksession name="all-rules"/>
</kbase>
</kmodule>
Copy the code
- You can have multiple kModules
kbase
, corresponding todrl
Rule file of kbase name="rules"
Name The name must be unique- There can be one or more Ksessions under kBase. The name attribute of ksession must be set and unique
- The default attribute of kbase indicates whether the current KieBase is default. If it is default, the KieBase can be found without the name, but each module can have at most one default KieBase
Rules /tree.drl & rules file
package rules; import org.itstack.demo.model.Policy import org.itstack.demo.Result; global org.itstack.demo.Result res; Rule "red A" when Policy(sex ==" male ", age < 18, userSingle) then res.setresult ("A"," red A"); End rule "red B" when Policy(sex ==" male ", age < 18,! UserSingle) then res.setresult ("B"," red B"); End rule "red C" when Policy(sex ==" male ", age >= 18, age <= 30, userMarry) then res.setresult ("C"," red C"); End rule "red" when Policy(sex == "male ", age >= 18, age <= 30,! UserMarry) then res.setresult ("D"," red D"); End rule "red E" when Policy(sex ==" male ", age > 30, userParenting) then res.setresult ("E"," red E"); End rule "red" when Policy(sex == "male ", age > 30,! UserParenting) then res.setresult ("F"," red F"); End rule "A" when Policy(sex == "female ", age < 18, userSingle) then res.setresult ("A"," YELLOW A"); End rule "yellow B" when Policy(sex ==" female ", age < 18,! UserSingle) then res.setresult ("B"," yellow B"); End rule "yellow C" when Policy(sex ==" female ", age >= 18, age <= 30, userMarry) then res.setresult ("C"," yellow C"); End rule "D" when Policy(sex ==" female ", age >= 18, age <= 30,! UserMarry) then res.setresult ("D"," D"); End rule "yellow E" when Policy(sex ==" female ", age > 30, userParenting) then res.setresult ("E"," yellow E"); End rule "yellow F" when Policy(sex ==" female ", age > 30,! UserParenting) then res.setresult ("F"," yellow F"); endCopy the code
- Rule name, when then end a set of combinations, under what conditions output what results
Sex == "female ", age > 30,! userParenting
“, separated by a comma is the condition of and, equivalent to your and. Not exactly, because in subsequent processing, the comma processing logic is optimized in Drools.- Then processes the result and returns the result information. This result uses the one we set
global
Global import. End end keyword. - Maybe you don’t think it’s very yours
if else
? But don’t feel that way, because this is just the tip of the iceberg. And we previously screenshot a tree structure, and this attribute structure can be generated automaticallyDRL
Rule file.
4. Perform the test
The startup process for Drools is set up in apitest.java & unit tests
public class ApiTest {
private KieContainer kieContainer;
private Policy policy;
@Before
public void init(a) {
/ / build KieServices
KieServices kieServices = KieServices.Factory.get();
kieContainer = kieServices.getKieClasspathContainer();
policy = new Policy();
policy.setSex("Male");
policy.setAge(16);
policy.setUserSingle(false);
policy.setUserMarry(false);
policy.setUserParenting(false);
System.out.println("Decision request:" + JSON.toJSONString(policy));
}
@Test
public void test_drools(a) {
KieSession kieSession = kieContainer.newKieSession("all-rules");
kieSession.insert(policy);
Result result = new Result();
kieSession.setGlobal("res", result);
int count = kieSession.fireAllRules();
System.out.println("The Fire rule (s) :" + count);
System.out.println("Drools:"+ result); kieSession.dispose(); }}Copy the code
The init () initialization
- In the initialization method, build
KieServices.Factory.get();
, this process is relatively resource – consuming and will not be built frequently in actual business use. - from
KieServices
To deriveKieContainer
Container for all kieBases of the given KieModule. - Set FACT objects, which are just conditional values for your decision object.
Test_drools () executes the rule
- Gets the session named all-rules in the configuration in kmodule.xml, which is stateful by default.
- Setting decision Objects
kieSession.insert(policy);
- Setting global Objects
kieSession.setGlobal("res", result);
Is used to finally output the result - Start executing rules
kieSession.fireAllRules()
- Finally output results, finally release resources
kieSession.dispose()
The test results
Decision request: {"age":16."sex":"Male"."userMarry":false."userParenting":false."userSingle":false}
Fire rule(s): 1 Decision result(Drools)B: B | redCopy the code
- You can try to modify the input parameter information during testing to verify different results.
5. Understanding of Rete algorithm
Drools is an open source rules engine written in the Java language that evaluates written rules using the Rete algorithm. Drools allows business logic to be expressed declaratively. Rules can be written in native languages other than XML, making them easy to learn and understand. Also, you can embed Java code directly into rules files, which makes learning Drools even more appealing.
Good! So you know, Drools is all about implementing the Rete algorithm. Let’s take a look at Rete.
In order to solve the problem of low efficiency of production-type reasoning engine, Forgy proposed Rete algorithm in 1979 as an efficient pattern matching algorithm for production-type system. The original purpose of Rete algorithm is to reduce the rule storage by using the common parts of each domain between rules, while saving the temporary results of the matching process to speed up the matching. In order to achieve this effect, the algorithm splits the rules, in which each condition unit is connected to a data discrimination network as a basic unit (node), and then the facts are filtered and propagated through the network. Finally, all the conditions are activated with fact-matching rules.
Since the Rete algorithm was proposed in 1979, it has undergone various improvements and expansions. In addition to the optimization of self-rule network structure, there are also many researches on some function extensions such as fuzzy reasoning, event reasoning and parallelization.
1. Structural optimization
-
Processing of mixed logic characters
Operators are logical operators that inject and, OR, not, etc.
-
Reordering of rule precursors
Rule antecedent order refers to the order of each constraint in the rule body. It determines the execution order of conditional link operations, affects the size of intermediate results, and is a key factor to determine the efficiency of rule matching.
-
Index method
The index method is to establish the index of the current node to the successor of nodes in the Rete network. In fact assertion, the index can be used to quickly find the corresponding successor nodes without searching one by one.
2. Function expansion
-
Rete was originally used to handle only first-order Boolean logic, but many Rete extensions are now used to handle other logic.
-
Event processing retes with time information express current state through facts, but many applications include some time in the event stream that plays a key role in the parallel execution of events. Therefore, Rete algorithm is needed to process these information.
3. Inference of special data
-
Flawed data and uncertain inference
- Is not correct
- Don’t precision
- inconsistencies
-
Fast-changing data and machine learning
In addition to data defects, Rete algorithm also needs to solve problems for the data with drastic changes.
4. The parallelization
Since the Rete algorithm was put forward, performance improvement has been the focus of research. After the advent of multi-core and multi-processor, it has become a common efficiency improvement method to distribute the inference process to different machines for parallel processing
Six, summarized
- Great products, great r&d, never just a microphone or a tool machine. But a craftsman with a soul, need to have a plan, decision-making, vision.
- Drools are not only used in this way, but also in a variety of ways. This chapter is mainly the beginning and will be further improved. About the engineering code can follow the public number (BugStack wormhole stack) to obtain.
- Only if your stack is comprehensive enough can you have a solution in N when you encounter a problem. But learning must be their own thing, whether busy or idle, to let their recharge. Entertainment is not impossible, but to control themselves properly.
If you don't control yourself, someone else will