javafluent

Fluent Inteface for Message Sender


I would like to create fluent API for message sender. Lets take simple example.

messageSender.newMessage()
    .withSomeField("some value")
    .withAnotherField("some value")
.publish();

I have clases messagePublisher and message. messagePublisher has method publish(message). How I can wrap this all together to achieve the fluent way as described above?

I have came up with solution where I have class 'messageSender' which contains instance of 'messagePublisher' and use it to publish message. When I call messageSender.newMessage() it will return messageBuilder but this messageBuilder needs to have reference to messageSender, so I am than able to call the publish() method. I do not like that messageBuilder has reverence to messageSender but I am not sure how to do it differently.

Thanks in advance for any help or suggestions!


Solution

  • You can use inner class for MessageSender:

    MessageSender.java:

    public class MessageSender {
      private MessagePublisher messagePublisher;
      public void setPublisher(MessagePublisher publisher) {
        this.messagePublisher = publisher;
      }
      public static void main(String[] args) {
        MessageSender messageSender = new MessageSender();
        messageSender.setPublisher(new MessagePublisher());
        messageSender.newMessage()
          .withDestination("DEST")
          .withMsg("message")
          .publish();
      }
    
      public MessageBuilder newMessage() {
        return new MessageBuilder();
      }
    
      class MessageBuilder {
        private Message message = new Message();
    
        public MessageBuilder withMsg(String msg) {
          message.setMsg(msg);
          return this;
        }
    
        public MessageBuilder withDestination(String destination) {
          message.setDestination(destination);
          return this;
        }
    
        public void publish() {
          messagePublisher.publish(message);
        }
      }
    }
    

    MessagePublisher.java:

    public class MessagePublisher {
      public void publish(Message message) {
        System.out.println(
          String.format(
            "Message to be sent: Msg=%s, Dest=%s", 
            message.getMsg(),
            message.getDestination()
          )
        );
      }
    }
    

    Message.java:

    public class Message {
      private String msg;
      private String destination;
    
      public void setMsg(String msg) {
        this.msg = msg;
      }
    
      public void setDestination(String destination) {
        this.destination = destination;
      }
    
      public String getMsg() {return this.msg;}
      public String getDestination() {return this.destination;}
    }