[JAVA] Have fun programming with lambda expressions and a fluid interface

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

Have fun programming with lambda expressions and a fluid interface
Exception handling with a fluid interface
Create exceptions with a fluid interface
Join a fun and fun programming study session!
Handle exceptions coolly with Java 8 lambda expressions and Stream API
About C # lambda expressions and Linq
Java lambda expressions learned with Comparator
Conditional branching with a flowing interface
Getting started with Java lambda expressions
A little understanding of lambda expressions
I wrote a Lambda function in Java and deployed it with SAM
Nowadays Java lambda expressions and Stream API
Draw a graph with Sinatra and Chartkick
Until programming beginners can use lambda expressions