Since I started using Java 8 for business, I've been looking for ways to write a little more fluent code using lambda expressions. I've finally written some nice code lately, so I'd love to share it with Java engineers, so I'm writing an article on Qiita for the first time.
This time, I would like to describe only the sample and introduce the mechanism behind it separately.
https://github.com/mt-village/nagare
The sample is a program that imitates the procedure for brewing coffee.
python
public void easygoing() {
WholeCoffeeBeans wholeBeans = WholeCoffeeBeans.inGrams(50);
GroundCoffeeBeans groundBeans = Mill.grind(wholeBeans);
Water water = Water.inMilliliters(500);
HotWater hotWater = Kettle.boil(water);
Coffee coffee = Dripper.drip(groundBeans, hotWater);
CoffeeAddict saya = new CoffeeAddict();
saya.drink(coffee);
}
Written in Japanese, it means that coffee beans are ground with a mill, hot water is boiled with a kettle, and Saya drinks coffee extracted with a dripper. I intentionally write it carefully without nesting, but it is quite troublesome because I have to write the mold one by one.
You can write the same process as follows
python
public void impatient() {
new CoffeeAddict().drink(Dripper.drip(
Mill.grind(WholeCoffeeBeans.inGrams(50)), Kettle.boil(Water.inMilliliters(500))));
}
It's a lot shorter, but it's a bit harsh to the human brain because it has a double-nested structure and must be interpreted in order from inside to outside.
Using the 8 classes added by nagare, the following description is possible.
python
public void nagare_prepositive() {
CoffeeAddict saya = new CoffeeAddict();
Do.when(WholeCoffeeBeans.inGrams(50), Water.inMilliliters(500))
.then(Do.first(Mill::grind).and(Kettle::boil))
.then(Dripper::drip)
.done(saya::drink);
}
python
public void nagare_postpositive() {
CoffeeAddict saya = new CoffeeAddict();
Do.first(Mill::grind).and(Kettle::boil)
.then(Dripper::drip)
.done(saya::drink)
.by(WholeCoffeeBeans.inGrams(50), Water.inMilliliters(500));
}
python
public void nagare_logic_and_exec() {
Saver<Coffee> brewCoffee = Do.when(WholeCoffeeBeans.inGrams(50), Water.inMilliliters(500))
.then(Do.first(Mill::grind).and(Kettle::boil))
.then(Dripper::drip);
CoffeeAddict saya = new CoffeeAddict();
saya.drink(brewCoffee.let());
}
The basic idea is similar to Stream added in Java 8. The first is the writing method that gives the argument first, the second is the writing method that gives the argument at the end, and the third is the writing method that separates logic and execution.
You can write a series of processes in the order from left to right (top to bottom), so once you get used to it, your thoughts and chords will match and it will be quite fun. Please try it with the code you write as a hobby. (I don't know if anyone writes Java as a hobby)
Samples are also included as unit tests, so if you are interested in combining them with the mechanism behind them, please take a look. https://github.com/mt-village/nagare
Recommended Posts