-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fizz buzz
This tutorial implements the FizzBuzz application with Easy Rules. FizzBuzz is a simple application that requires to count from 1 to 100 and:
- print "fizz" if the number is multiple of 5
- print "buzz" if the number is multiple of 7
- print "fizzbuzz" if the number is multiple of 5 and 7
- print the number itself otherwise
Here is a FizzBuzz example from Java Examples in a Nutshell book :
public class FizzBuzz {
public static void main(String[] args) {
for(int i = 1; i <= 100; i++) {
if (((i % 5) == 0) && ((i % 7) == 0))
System.out.print("fizzbuzz");
else if ((i % 5) == 0) System.out.print("fizz");
else if ((i % 7) == 0) System.out.print("buzz");
else System.out.print(i);
System.out.println();
}
System.out.println();
}
}
We will write one rule for each requirement:
@Rule
public class FizzRule {
@Condition
public boolean isFizz(@Fact("number") Integer number) {
return number % 5 == 0;
}
@Action
public void printFizz() {
System.out.print("fizz");
}
@Priority
public int getPriority() {
return 1;
}
}
@Rule
public class BuzzRule {
@Condition
public boolean isBuzz(@Fact("number") Integer number) {
return number % 7 == 0;
}
@Action
public void printBuzz() {
System.out.print("buzz");
}
@Priority
public int getPriority() {
return 2;
}
}
public class FizzBuzzRule extends UnitRuleGroup {
public FizzBuzzRule(Object... rules) {
for (Object rule : rules) {
addRule(rule);
}
}
@Override
public int getPriority() {
return 0;
}
}
@Rule
public class NonFizzBuzzRule {
@Condition
public boolean isNotFizzNorBuzz(@Fact("number") Integer number) {
// can return true, because this is the latest rule to trigger according to assigned priorities
// and in which case, the number is not fizz nor buzz
return number % 5 != 0 || number % 7 != 0;
}
@Action
public void printInput(@Fact("number") Integer number) {
System.out.print(number);
}
@Priority
public int getPriority() {
return 3;
}
}
Here are some explanations of these rules:
-
FizzRule
andBuzzRule
are straightforward, they check if the input is fizz or buzz and print the result -
FizzBuzzRule
is composite rule. We will create it with two composing rules:FizzRule
andBuzzRule
. The choice of the base class asUnitRuleGroup
is important: Either both rules are satisfied and applied or nothing is applied. -
NonFizzBuzzRule
is for numbers that are not fizz nor buzz.
Note that we've set priorities so that rules are fired in the same order as the example from Java Examples in a Nutshell.
Then, we have to register these rules in a rules set and fire them using a rules engine:
public class FizzBuzzWithEasyRules {
public static void main(String[] args) {
// create a rules engine
RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);
// create rules
Rules rules = new Rules();
rules.register(new FizzRule());
rules.register(new BuzzRule());
rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));
rules.register(new NonFizzBuzzRule());
// fire rules
Facts facts = new Facts();
for (int i = 1; i <= 100; i++) {
facts.put("number", i);
fizzBuzzEngine.fire(rules, facts);
System.out.println();
}
}
}
Note that we have set the skipOnFirstAppliedRule
parameter to skip subsequent rules whenever a rule is applied.
To run this tutorial, you can follow these instructions:
$ git clone https://github.com/j-easy/easy-rules.git
$ cd easy-rules
$ mvn install
$ cd easy-rules-tutorials
$ mvn exec:java -P runFizzBuzzTutorial
You should get the following output:
1
2
3
4
fizz
6
buzz
8
9
fizz
11
12
13
buzz
fizz
16
17
18
19
fizz
buzz
22
23
24
fizz
26
27
buzz
29
fizz
31
32
33
34
fizzbuzz
36
37
38
39
fizz
41
buzz
43
44
fizz
46
47
48
buzz
fizz
51
52
53
54
fizz
buzz
57
58
59
fizz
61
62
buzz
64
fizz
66
67
68
69
fizzbuzz
71
72
73
74
fizz
76
buzz
78
79
fizz
81
82
83
buzz
fizz
86
87
88
89
fizz
buzz
92
93
94
fizz
96
97
buzz
99
fizz
In this tutorial, you have seen how to create rules, compose them and fire them in a particular order.
Easy Rules implementation of FizzBuzz my appear an overkill compared to the naive solution. This is true! Don't use Easy Rules to implement FizzBuzz application. We have used it here for demonstration purpose.
But when you start to have dozen of business rules, a naive solution with multiple nested if/then/else statements will quickly become hard to read, understand, test and maintain. With Easy Rules, you can design rules to do one thing (and do it well), that are easy to read, understand, unit test and compose.
Easy Rules is created by Mahmoud Ben Hassine with the help of some awesome contributors
-
Introduction
-
User guide
-
Tutorials
-
Get involved