small medium large xlarge

Generic-user-small
23 Dec 2015, 10:28
Vijay S (1 post)

Hi Venkat,

Thanks for the wonderful book and I love your flow and presentation style. I wanted to understand little more about the Fluent style example detailed in page: 82 (copied code below).

The send() method is accepting Consumer of type FluentMailer but a new instance of FluentMailer is created and passed to the Consumer’s accept() method. How does the mail metadata values (from, to, subject etc.,) gets passed to the Consumer to validate? Probably I am not understanding the flow proeprly. Appreciate if you could clarify?

public class FluentMailer {
  private FluentMailer() {}
  
  public FluentMailer from(final String address) { /*... */; return this; }
  public FluentMailer to(final String address)   { /*... */; return this; }
  public FluentMailer subject(final String line) { /*... */; return this; }
  public FluentMailer body(final String message) { /*... */; return this; }
  
  public static void send(final Consumer<FluentMailer> block) { 
    final FluentMailer mailer = new FluentMailer();
    block.accept(mailer);
    System.out.println("sending..."); 
  }

  //...
  public static void main(final String[] args) {
    FluentMailer.send(mailer ->
      mailer.from("build@agiledeveloper.com")
            .to("venkats@agiledeveloper.com")
            .subject("build notification")
            .body("...much better..."));
  }
} 
Venkatsubramaniam_pragsmall
06 Jan 2016, 20:09
Venkat Subramaniam (99 posts)

Hi Vijay, sorry about the delayed response. Thank you for your kind words.

The send method is creating a mailed object and calls the lambda expression. Within the lambda express the methods like from, to, etc. are invoked on the instance of Mailer passed in. The functions like from can either update the Mailer instance or they can create a new Mailer instance.

If they update the instance, then when the lambda completes the send function has an updated Mailer instance from which it can pull the necessary data for validation.

If they return a new instance instead, then we can change the send method to take in a Function<> instead of Consumer<> and that way the send can get access to the Mailer instance returned by the call function (say, body) in the chain.

I hope this helps answer your question,

Thank you.

Generic-user-small
15 Nov 2016, 13:15
Per Kromann Jacobsen (1 post)

Hi Venkat, Let me first say that I am enjoying your book a lot. It is instructive and entertaining at the same time. There is something I am wondering about, though. On page 82 you wrote “Also, there are a lot of corner cases—for example, we have to ensure methods like from() are called exactly once. We need to refine the design further to make it more intuitive and fluent. Let’s call our friends, lambda expressions, for help.” Next you develop an improvement of MailBuilder called FluentMailer which is more elegant. But does FluentMailer ensure that from() is called exactly once?

Venkatsubramaniam_pragsmall
15 Nov 2016, 16:18
Venkat Subramaniam (99 posts)

Hi Per,

Thank you.

The code as is does not ensure that from is called only once. The fluency (reduced noise) and the flow makes it easier to see if we’re calling it more than once. We can also modify the implementation of from to check and ensure if needed. This latter solution is true for other implementations as well, however.

Regards,

Venkat

You must be logged in to comment