Java Builder Pattern Example

This is an example to demonstrate how to use the Builder Pattern in Java. The main advantage of using a Builder Pattern in this example is to deal with the various number of optional parameters of Contact class.
The Contact class in this example keeps track of a person's Contacts information. The Contact class has fields that are not required to be set. The user of this class only sets the fields he need by using the Builder Pattern.

Contact Class:

package edu.nyu.pqs;

/** This is an immutable, underivable Contact class that implements Comparable
 * overrides toString and hashCode methods, uses Builder pattern to
 * deal with its large number of optional parameters.
 * All of its fields are final to provide the immutability.
 * The class is final to make it underivable 
 */
public final class Contact implements Comparable { 
 private final String name;
 private final String jobTitle;
 private final String company;
 private final String email;
 private final String workPhone;
 private final String mobilePhone;
 private final String address;
 private final String notes; 
 /** to avoid concatenation cost each time the toString method is invoked,
  * the String version of the class is stored as a field and initialized 
  * once the build method is invoked.
 */
 private final String stringFormofContact;
 /** to avoid calculation cost each time the hashCode method is invoked,
  * the hash code is stored as a field and initialized 
  * once the build method is invoked.
 */
 private final int hashcode;
 
 /** The member class of the Contact class which helps the Contact class
  * to easily deal with large number of optional parameters
  */
 public static class Builder{  
  private String name ="";
  private String jobTitle ="";
  private String company="";
  private String email ="";
  private String workPhone="";
  private String mobilePhone="";
  private String address="";
  private String notes="";
  
  /**
   * Sets the name field of the Builder class
   * @param val , String value to set the name 
   * field of the Builder and so the Contact class
   */
  public Builder name (String val){   
   name=val; return this;
  }
  
  /**
   * Sets the company field of the Builder class
   * @param val , String value to set the company 
   * field of the Builder and so the Contact class
   */
  public Builder company (String val){   
   company=val; return this;
  }
  
  /**
   * Sets the jobTitle field of the Builder class
   * @param val , String value to set the jobTitle 
   * field of the Builder and so the Contact class
   */
  public Builder jobTitle (String val){   
   jobTitle=val; return this;
  }
  
  /**
   * Sets the email field of the Builder class
   * @param val , String value to set the email 
   * field of the Builder and so the Contact class
   */
  public Builder email (String val){   
   email=val; return this;
  }
  
  /**
   * Sets the workPhone field of the Builder class
   * @param val , String value to set the workphone 
   * field of the Builder and so the Contact class
   */
  public Builder workPhone (String val){   
   workPhone=val; return this;
  }
  
  /**
   * Sets the mobilePhone field of the Builder class
   * @param val , String value to set the mobilePhone 
   * field of the Builder and so the Contact class
   */
  public Builder mobilePhone (String val){   
   mobilePhone=val; return this;
  }
  
  /**
   * Sets the address field of the Builder class
   * @param val , String value to set the address 
   * field of the Builder and so the Contact class  
   */
  public Builder address (String val){   
   address=val; return this;
  }
  
  /**
   * Sets the notes field of the Builder class
   * @param val , String value to set the notes 
   * field of the Builder and so the Contact class
   */
  public Builder notes (String val){   
   notes=val; return this;
  }
  
  /**
   * Builds the Contact class using methods called from Builder class 
   * to the builder class
   */
  public Contact build (){   
   return new Contact(this);
  }  
 }
 
 /** Initializes the fields of the Contact class 
  *  benefiting from the Builder class
  *  @param builder, the builder which is called to initiate 
  *  the fields of Contact class instance 
  */
 private Contact(Builder builder){
  name= builder.name ;
  jobTitle = builder.jobTitle;
  company = builder.company;
  email = builder.email;
  workPhone = builder.workPhone;
  mobilePhone = builder.mobilePhone;
  address = builder.address;
  notes = builder.notes;
  stringFormofContact = convertFieldsToString();
  hashcode = calculateHashCode() ;
 }
 
 /** suppresses default constructor for noninstantiability
  * throws AssertionError if it is being called 
  */
 private Contact(){
  throw new AssertionError();
 }
 
 /** Returns the name field of the class
  */
 public String getName() {
  return name;
 }

 /** Returns the jobTitle field of the class
  */
 public String getJobTitle() {
  return jobTitle;
 }

 /** Returns the company field of the class
  */
 public String getCompany() {
  return company;
 }

 /** Returns the email field of the class
  */
 public String getEmail() {
  return email;
 }

 /** Returns the workPhone field of the class
  */
 public String getWorkPhone() {
  return workPhone;
 }

 /** Returns the mobilePhone field of the class
  */
 public String getMobilePhone() {
  return mobilePhone;
 }

 /** Returns the address field of the class
  */
 public String getAddress() {
  return address;
 }

 /** Returns the notes field of the class
  */
 public String getNotes() {
  return notes;
 }
 
 /** If the two given objects are the same,
  * function returns true.
  * If the Object to be compared is not an instance of the Contact class,
  * function returns false.
  * Otherwise, function compares each of the fields in the class
  */
 @Override public boolean equals(Object o){  
  if (o == this) return true;
  if(!(o instanceof Contact)) return false;  
  Contact cntct = (Contact) o;  
  return cntct.name.equals(name) && 
    cntct.jobTitle.equals(jobTitle) && 
    cntct.email.equals(email) && 
    cntct.workPhone.equals(workPhone) &&
    cntct.mobilePhone.equals(mobilePhone) &&
    cntct.address.equals(address) &&
    cntct.notes.equals(notes);
 }
 
 /** Converts a given Contact class instance into String. 
  * Fields are separated by line breaks and are labeled as they are 
  * converted into String 
  * 
  * @return The String equivalent of a Contact class instance 
  */
 @Override public String toString(){
  return stringFormofContact;
 }
 
 /** This function is called only when the build() method is invoked. 
  *  Returns the String version of the each fields by adding them a label.
  */
 private String convertFieldsToString() { 
  return ("Name: "+name+"\nJob Title: "+jobTitle+ 
      "\nCompany: "+company+"\nEmail: "+email+
      "\nWork Phone: "+workPhone+
      "\nMobile Phone: "+mobilePhone+ 
      "\nAddress: "+address+"\nNotes: "+notes) ;
 }
 
 /** Returns the hash code value for a given class instance 
  * The code was already created just after other fields of
  * the Contact class are initialized by calling the calculateHashCode
  * method.
  */
 @Override public int hashCode(){
  return hashcode; 
 }
 
 /** Returns the hash code value for the current class
  * The code is generated by calculating the hash code values of each 
  * field and multiplying those values by some constant
  */
 private int calculateHashCode(){
  int result = 17;
  result = 31*result+name.hashCode();
  result = 31*result+jobTitle.hashCode();
  result = 31*result+company.hashCode();
  result = 31*result+email.hashCode();
  result = 31*result+workPhone.hashCode();
  result = 31*result+mobilePhone.hashCode();
  result = 31*result+address.hashCode();
  result = 31*result+notes.hashCode();
  return result ;
 }
 
 /**
  * Compares two Contact classes
  * 
  * @return  Positive integer if left hand side of the compared 
  * objects is bigger than the right hand side
  *    Negative integer if left hand side of the compared 
  * objects is smaller than the right hand side
  *    Zero if left hand side of the compared 
  * objects is equal to the right hand side
  */
 public int compareTo(Contact cntct){
  int comparisionReslt = name.compareTo(cntct.name);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = jobTitle.compareTo(cntct.jobTitle);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = company.compareTo(cntct.company);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = email.compareTo(cntct.email);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = workPhone.compareTo(cntct.workPhone);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = mobilePhone.compareTo(cntct.mobilePhone);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = address.compareTo(cntct.address);
   if(comparisionReslt != 0) return comparisionReslt ;
  comparisionReslt = notes.compareTo(cntct.notes);
   return comparisionReslt ;
 } 
}


How To Use it:
package edu.nyu.pqs;

public class TryContact {

 public static void main(String[] args) {
  // Create a Contact instance
  Contact c = new Contact.Builder().name("Mahir").notes("My School Friend").build();
  // Print it
  System.out.print(c);
 }
}

No comments:

Post a Comment

Python Line Profilers using Decorator Pattern

You can use any of the following decorators to profile your functions line by line.  The first one(Profiler1) is a decorator as a class and...