6

I came across the following code. Is there any reason why it has used used return this?

public class EmailUtil {
       private Messaging.SingleEmailMessage singleEmailMessage;
       private final List<String> toAddresses;

       //optional parameters set to default        
       private String subject = '';
       private String htmlBody = ''; 
       private Boolean useSignature = false;
       private List<Messaging.EmailFileAttachment> fileAttachments = null;
       //defaults to current user's first name + last name
       private String senderDisplayName = UserInfo.getFirstName()+' '+UserInfo.getLastName();
       //get the current user in context
       User currentUser = [Select email from User where username = :UserInfo.getUserName() limit 1];        
       //replyTo defaults to current user's email 
       private String replyTo = currentUser.email;
       private String plainTextBody = '';

       public EmailUtil(List<String> addresses) {
           this.toAddresses = addresses;
       }

       public EmailUtil senderDisplayName(String val) {
           senderDisplayName = val;
           return this;
       }

       public EmailUtil subject(String val) {
           subject = val;
           return this;
       }

       public EmailUtil htmlBody(String val) {
           htmlBody = val;
           return this;
       }

       public EmailUtil useSignature(Boolean bool) {
           useSignature = bool;
           return this;
       }

       public EmailUtil replyTo(String val) {
           replyTo = val;
           return this;
       }

       public EmailUtil plainTextBody(String val) {
           plainTextBody = val;
           return this;
       }

       public EmailUtil fileAttachments(List<Messaging.Emailfileattachment> val) {
           fileAttachments = val;
           return this;
       }

       //where it all comes together
       //this method is private and is called from sendEmail()
       private EmailUtil build() {
           singleEmailMessage = new Messaging.SingleEmailMessage();
           singleEmailMessage.setToAddresses(this.toAddresses);
           singleEmailMessage.setSenderDisplayName(this.senderDisplayName);
           singleEmailMessage.setSubject(this.subject);
           singleEmailMessage.setHtmlBody(this.htmlBody);
           singleEmailMessage.setUseSignature(this.useSignature);
           singleEmailMessage.setReplyTo(this.replyTo);
           singleEmailMessage.setPlainTextBody(this.plainTextBody);
           singleEmailMessage.setFileAttachments(this.fileAttachments);
           return this;
       }

       //send the email message
       public void sendEmail() {
              try {
                  //call build first to create the email message object
                  build();
                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { singleEmailMessage });
              } catch (Exception ex) {
                  throw new GenericException('There was a problem while calling Messaging.sendEmail()');
              }                
       }    

   } 

Source : http://developer.force.com/cookbook/recipe/email-utility-class

  • 1
    I don't see any reason why that's useful to return this. I think that's probably really bad design. All these methods should be void. – Martin Lezer Jan 24 '17 at 13:54
  • I agree, I do not see any reason. Can you give an example where return this is useful? – Cuban coffee Jan 24 '17 at 13:57
  • 4
    Method chaining - Its a design pattern for a specific type of problem! – Raul Jan 24 '17 at 13:59
  • I don't see any problem when calling each method on a new line. That's just developer laziness :D – Martin Lezer Jan 24 '17 at 14:03
  • 1
    @MartinLezer Note the link Rahul gave. It's to solve a SPECIFIC type of problem. Note that these are private variables with no setters or getters. VOID methods wouldn't do what you'd expect them to do since the variables haven't been declared as apex properties. – crmprogdev Jan 24 '17 at 14:19
14

This way you can call your methods "as a flow" to generate an object:

EmailUtil email = new EmailUtil(new String[] {})
  .subject('My subject')
  .htmlBody('my body')
  .senderDisplayName('My name');

Because you return the current object with this you can access it and its methods/attributes.

I personally like this way to do.

  • 2
    Wow I never thought of that. That's great. What about performance? Is there any impact possible? – Martin Lezer Jan 24 '17 at 13:59
  • Performances are the ~same (depending of the use case) – Simon Placentino Jan 24 '17 at 14:03
  • 1
    Ok I will try some tests with this class :D See you in 2 hours. – Martin Lezer Jan 24 '17 at 14:04
  • 2
    @MartinLezer Some food for though: premature optimization is the root of all evil. – Keith C Jan 24 '17 at 14:08
  • 1
    A good use case for this pattern is (but is not on Salesforce) HTTPRequest setting. It is more readable to do so: HTTPRequest request = new HTTPRequest().setMethod('GET').setEndpoint('www.salesforce.com').setHeader('Xx', 'Yy').setTimeout(2000); – Simon Placentino Jan 24 '17 at 15:03
4

It's called Fluent Pattern, and as already mentioned, it enables chaining. You can see it demonstrated in the Composite pattern in Apex Design Patterns.

It's worth reading the excellent answers on Why Would I Not Enable Chaining? for a deeper dive into the impact, but it's incredibly useful for building data. For example, I use it in my SObjectFactory library to simplify specification of multiple fields.

List<Opportunity> records = new SObjectBuilder(Opportunity.sObjectType)
    .put (Opportunity.AccountId, SObjectFactory.provideGenericParent(Account.sObjectType))
    .put(Opportunity.CloseDate, Date.today())
    .count (Limits.getLimitQueries() + 1)
    .create().getRecords();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.