Optional Parameters Handling Strategy In Java And Comparision

Optional Parameters handling Strategy

Often we face a situation where we need to design an Object which expects lot of parameters from client. Some of parameters are required and some of them are optional. In this article we will focus on various strategies by which we can design such objects and their pros and cons

Strategy 1. Telescopic constructors
To design such objects, we can use chain of overloading constructors. First minimal constructor is taking only required parameters then delegate call another constructor which takes an optional parameter
Then this constructor calls another which takes another optional parameter until all optional parameters are covered.  When calling another constructor, it can pass default value for optional parameter.

Pros:
1.    For less number of parameters this is good way to design object.
2.    Very easy to implement.
Cons:
1.    For large number of parameters, it creates problems. Developer often confuse while passing parameters.
2.    If two adjacent parameters have same datatype and developer unintentionally swap values. Compiler not complain but it creates a genuine problem in runtime and very hard to track.

Example:
package com.example.builder;

public class EmployeeTelescopic {
      
       private String name;
       private Integer empId;
       private String company;
       private Integer passport;
       private String tempAddress ;
      
      
       public EmployeeTelescopic(String name,Integer empId,String company)
       {
              this(name,empId,company,0);
       }
      
       public EmployeeTelescopic(String name,Integer empId,String company,int passport)
       {
              this(name,empId,company,passport,"NA");
       }
      
       public EmployeeTelescopic(String name,Integer empId,String company,Integer passport,String tempAddress)
       {
              this.name=name;
              this.empId=empId;
              this.company=company;
              this.passport=passport;
              this.tempAddress=tempAddress;
             
       }
      
      
      
      
       @Override
       public String toString() {
              return "EmployeeTelescopic [name=" + name + ", empId=" + empId
                           + ", company=" + company + ", passport=" + passport
                           + ", tempAddress=" + tempAddress + "]";
       }

       public static void main(String[] args) {
             
              EmployeeTelescopic emp = new EmployeeTelescopic("Shamik",100,"IBM");
              EmployeeTelescopic emp1 = new EmployeeTelescopic("Akash",101,"IBM",1234,"1,bangalore");
              System.out.println(emp);
              System.out.println(emp1);
       }

}


Strategy 2By getters/setters

Create a class and exposing every property through setters/getters. Client will set the property using setter, access it via getters.

Pros:
1.    Easy to implement.
2.    In setters you can put validation or pass default value for optional parameters.

Cons:

1.    If object is share between multiple thread it can be happened that one thread just create the object and try to set the properties while other thread accesses this object, but as its properties have not been set yet wired exception can occur.


2.    As properties are exposed through setters/getters to make this object immutable need extra care.



Strategy 3. Using Varargs

Create a constructor like, Employee(Object… args) ,now client can pass variable length parameters. Constructor then checking the type of each parameter by instanceof operator.
If type is same as bean property set value else throw IllegalArgumentException.

Pros:
1.    No such.

Cons:

1.For each property you need to check type so it loses static type checking.
2. There is a conditional block for each property which increase cyclomatic complexity.



Strategy 4. Using Map

Same as varargs instead of varargs here we use a map.


Pros:
1.    No such.

Cons:

1.For each property you need to check type so it loses static type checking.
2. There is a conditional block for each property which increase cyclomatic complexity.



Example:

package com.example.builder;

import java.util.HashMap;
import java.util.Map;

public class EmployeeMap {
      
       private String name;
       private Integer empId;
       private String company;
       private Integer passport;
       private String tempAddress ;
      
      
       EmployeeMap(Map<String,Object> map) throws IllegalArgumentException
       {
              if(!(map.containsKey("name") && map.containsKey("empId") && map.containsKey("company")))
              {
                     throw new IllegalArgumentException("Required  Parameter missing");
              }
              if((map.get("name")==null || map.get("empId")==null ||  map.get("company")==null))
              {
                     throw new IllegalArgumentException("Required  Parameter missing");
              }
             
              if(map.get("name") instanceof String)
              {
                     this.name =(String) map.get("name") ;
              }
              else{
                     throw new IllegalArgumentException("name Parameter  type is wrong");
              }
             
              if(map.get("empId") instanceof Integer)
              {
                     this.empId =(Integer) map.get("empId") ;
              }
              else{
                     throw new IllegalArgumentException("enpId Parameter  type is wrong");
              }
              if(map.get("company") instanceof String)
              {
                     this.company =(String) map.get("company") ;
              }
              else{
                     throw new IllegalArgumentException("company Parameter  type is wrong");
              }
             
             
              if(map.containsKey("passport") && (map.get("passport") instanceof Integer))
              {
                     this.passport = (Integer)map.get("passport");
              }
              else
              {
                     this.passport=0;
              }
             
              if(map.containsKey("tempAddress") && (map.get("tempAddress") instanceof String))
              {
                     this.tempAddress = (String)map.get("tempAddress");
              }
              else
              {
                     this.tempAddress="NA";
              }
       }
      
      
      
       @Override
       public String toString() {
              return "EmployeeMap [name=" + name + ", empId=" + empId + ", company="
                           + company + ", passport=" + passport + ", tempAddress="
                           + tempAddress + "]";
       }



       public static void main(String[] args) {
             
              try
              {
              Map map = new HashMap<String,Object>();
              map.put("name", "Shamik");
              map.put("empId", 100);
              map.put("company", "IBM");
              EmployeeMap emp = new EmployeeMap(map);
             
              Map map1 = new HashMap<String,Object>();
              map1.put("name", "Akash");
              map1.put("empId", 101);
              map1.put("company", "IBM");
              map1.put("passport", "1234");
              map1.put("tempAddress", "1,bangalore");
              EmployeeMap emp1 = new EmployeeMap(map1);
             
              System.out.println(emp);
              System.out.println(emp1);
             
              }
              catch(IllegalAccessException ex)
              {
                     ex.printStackTrace();
              }
       }

}
Strategy 5: Null values


Here client pass optional value as null and constructor checks if value is null then set default value for optional parameters, if parameter is required  and null ,constructor throws an exception.



Pros:
3.    For less number of parameters this is good way to design object.
4.    Very easy to implement.
Cons:
3.    For large number of parameters, it creates problems. Developer has to pass null value for optional parameters.
4.    If two adjacent parameters have same datatype and developer unintentionally swap values. Compiler not complain but it creates a genuine problem in runtime and very hard to track.


Example:

package com.example.builder;

public class EmployeeNull {
      
       private String name;
       private Integer empId;
       private String company;
       private Integer passport;
       private String tempAddress;
      
      
       public EmployeeNull(String name,Integer empId,String company,Integer passport,String tempAddress) throws IllegalArgumentException
       {
              if(name ==null && empId==null && company==null)
              {
                     throw new IllegalArgumentException("Required  Parameter missing");
              }
             
              this.name=name;
              this.empId=empId;
              this.company=company;
              this.passport= passport != null?passport:0;
              this.tempAddress = tempAddress !=null? tempAddress:"NA";
       }


       @Override
       public String toString() {
              return "EmployeeNull [name=" + name + ", empId=" + empId + ", company="
                           + company + ", passport=" + passport + ", tempAddress="
                           + tempAddress + "]";
       }
      
      
       public static void main(String[] args) throws IllegalAccessException {
             
              EmployeeNull emp = new EmployeeNull("Shamik",100,"IBM",null,null);
              EmployeeNull emp1 = new EmployeeNull("Akash",101,"IBM",1234,"1,blore");
              System.out.println(emp);
              System.out.println(emp1);
             
       }
      
      
}


Strategy 6. Builder Pattern

Use a nested static class which act as builder of this bean. Builder takes require parameters as it’s constructor arguments and for each optional parameter there will be a helper method which set the value and return Builder instance itself. So we can invoke another helper method for parameter. Builder pattern maintains fluent interface pattern (Channing of methods).  At last build() method return an Immutable  bean object.

Pros:
1.    Immutability achieve easily so Object is thread safe by design.
2.    To set optional parameters, parameter position is not necessary as each parameter has helper method client can invokes them. It offers fluidity by chain of methods pattern.
Cons:
1.    Complex to implement

Example:

package com.example.builder;

public class Employee {
      
       private String name;
       private Integer empId;
       private String company;
       private Integer passport;
       private String tempAddress ;
      
       private Employee()
       {
             
       }
       private static class EmployeeBuilder
       {
              private String name;
              private Integer empId;
              private String company;
              private Integer passport;
              private String tempAddress ;
              public EmployeeBuilder(String name,Integer empId,String company)
              {
                     this.name=name;
                     this.empId=empId;
                     this.company=company;
              }
             
              public EmployeeBuilder setPassport(Integer passport)
              {
                     this.passport=passport;
                     return this;
                    
              }
             
              public EmployeeBuilder setTempAddress(String address)
              {
                     this.tempAddress=address;
                     return this;
                    
              }
             
              public Employee build()
              {
                     Employee emp = new Employee();
                    
                     emp.name=this.name;
                     emp.empId=this.empId;
                     emp.company=this.company;
                     emp.passport=this.passport!=null?this.passport:0;
                     emp.tempAddress=this.tempAddress!=null?this.tempAddress:"NA";
                     return emp;
              }

             
             
             
             
             
       }
      
      
      
       @Override
       public String toString() {
              return "Employee [name=" + name + ", empId=" + empId + ", company="
                           + company + ", passport=" + passport + ", tempAddress="
                           + tempAddress + "]";
       }



       public static void main(String[] args) {
             
              Employee emp = new Employee.EmployeeBuilder("Shamik", 100, "IBM").build();
              Employee emp1 = new Employee.EmployeeBuilder("Akash", 101, "IBM").setPassport(1234).setTempAddress("1,bangalore").build();
              System.out.println(emp);
              System.out.println(emp1);
       }
      

}





Comparison: Please find the picture below.


  
Conclusion:  For fewer parameters like 4 or less use Telescopic constructor pattern

For larger number of parameters use Builder pattern.


Java Fluent API Design

In this article we will discuss about how to design fluent API in Java. The term Fluent interface is coined by Martin Fowler and Eric Evans. Fluent API means, build an API in such way so that same meets following criteria.
a.       API user can understand API very easily.
b.       API can perform a series of actions in order to finish a task, in java we can do it by series of method calls (Chaining of methods).
c.       Each Methods name should be Domain specific terminology.
d.       API should suggestive enough to guide API Users, what to do next and What are the possible operations users can take at a particular moment.
Suppose You want to Design an API for a Domain, say (Retail) so There should be some common terminology exists in Retail domain and for a certain context(Task) it will take a series of actions to finish this task. Say for an invoice generation it has to follow certain steps. Now when you design API, you should design it such a way, when API Users call Billing Service for invoice generation, API User can fluently perform each step in order to complete invoice generation and API will assist user to perform those steps upon invoking Billing Service. When a API method invokes by an user, method will perform its task and returns a Domain Object which will assist what to do next, until all steps are executed.  Unlike Standard API it is API user job to call API methods in a sequential way to successfully performs a task. So API Users has to know about the service steps very well.


Design A Fluent API:









   Example: Suppose we want to design a API for Restaurant.
As a customer of this Restaurant, one should follow below steps

In a Standard API design, we should do the following:
1.       Create a Restaurant interface.
2.        Create an Implementation class of Restaurant interface. Compose Menucard  class into it.
3.       Create getters and setters for restaurant properties like name, address.
4.       In MenuCard class maintain a List of menu Items . Expose some methods like showmenu(). Ordermenu(); etc.
5.       Each menu Items has name and cost properties and corresponding getters/setters.
6.      When API User call this API he/she will call a sequence of methods(Enter Resturent,call showMenu() then Ordermenu() etc.) to perform above Steps shown in the picture.

So it is not fluent lot of sequential statement needs to perform to complete task and API user has to know the sequence .

Now I will show you How we will design a Fluent API.
Java code:
package com.example.fluentapi.contract;

public interface IResturant {
      
       public IResturant name(String name);
       public IMenu show();
      
      

}


package com.example.fluentapi.contract;

public interface IMenu{
      
       public IMenu order(int index);
       public IMenu eat();
       public IMenu pay();
       public IItem get(int index);

}

package com.example.fluentapi.contract;

public interface IItem {
      
       public IItem name();
       public Integer cost();
      

}

Implementation:
package com.example.fluentapi.impl;

import com.example.fluentapi.contract.IMenu;
import com.example.fluentapi.contract.IResturant;

public class Arsalan implements IResturant{

                String name;
                String IMenu;
               
                public IResturant name(String name) {
                                this.name=name;
                                System.out.println("Enter to hotel :: " + name);
                                return this;
                }

               
                public IMenu show() {
                                // TODO Auto-generated method stub
                                ArsalanMenuHandler handler = new ArsalanMenuHandler();
                                handler.showMenu();
                                return handler;
                }

}

package com.example.fluentapi.impl;

import java.util.ArrayList;
import java.util.List;

import com.example.fluentapi.contract.IItem;
import com.example.fluentapi.contract.IMenu;

public class ArsalanMenuHandler implements IMenu{

                List<IItem> menuList = new ArrayList<IItem>();
                List<IItem> selectedList = new ArrayList<IItem>();
               
                public ArsalanMenuHandler()
                {
                                IItem biriyani = new IItem(){
                                                public IItem name()
                                                {
                                                                System.out.println("Mutton Biriyani");
                                                                return this;
                                                }
                                                public Integer cost()
                                                {
                                                                return 180;
                                                }
                                };
                                IItem muttonChap = new IItem(){
                                                public IItem name()
                                                {
                                                                System.out.println("Mutton Chap");
                                                                return this;
                                                }
                                                public Integer cost()
                                                {
                                                                return 160;
                                                }
                                };
                                IItem firni = new IItem(){
                                                public IItem name()
                                                {
                                                                System.out.println("Firni");
                                                                return this;
                                                }
                                                public Integer cost()
                                                {
                                                                return 100;
                                                }
                                               
                                               
                                };
                                menuList.add(biriyani);
                                menuList.add(muttonChap);
                                menuList.add(firni);
                               
                }
                public IMenu order(int index) {
                                // TODO Auto-generated method stub
                                IItem item =get(index);
                                selectedList.add(item);
                                System.out.println("Order given ::");
                                item.name();
                                return this;
                }

               
                public IMenu eat() {
                                for(IItem item : selectedList)
                                {
                                                System.out.println("eating ");
                                                item.name();
                                }
                                return this;
                }

               
                public IMenu pay() {
                                int cost=0;
                                for(IItem item : selectedList)
                                {
                                                cost = cost + item.cost();
                                }
                                System.out.println("Paying Ruppes" + cost);
                                return this;
                }
                @Override
                public IItem get(int index) {
                                // TODO Auto-generated method stub
                                if(index <3)
                                {
                                                return menuList.get(index);
                                }
                                return null;
                               
                }
               
                public void showMenu(){
                                System.out.println("MENU IN ARSALAN");
                                for(IItem item : menuList)
                                {
                                               
                                                item.name();
                                               
                                }
                               
                }

}

Test Fluent API:
package com.example.fluentapi.impl;

public class FluentApiTest {
      
       public static void main(String[] args) {
             
              new Arsalan().name("ARSALAN").show().order(0).order(1).eat().pay();
       }

}
Output :
Enter to hotel :: ARSALAN
MENU IN ARSALAN
Mutton Biriyani
Mutton Chap
Firni
Order given ::
Mutton Biriyani
Order given ::
Mutton Chap
eating
Mutton Biriyani
eating
Mutton Chap
Paying Ruppes340

Look How we perform the steps fluently by calling series of methods
new Arsalan().name("ARSALAN").show().order(0).order(1).eat().pay();

This is a test example, to make it more polished we need to work on following things
1.  Order method should take MenuItem instead of position also needs to handle Exception scenarios. If a MenuItem not found.
2.  Order can be cancelled.
3.  Pay must have payment mode. (creditcard, debitcard, Cash)
4.  May user can pay tips and it should be optional.
5.  In course of eating, he/she can Order more items, so make an order functionality should be available in course of eating.
6.  Tax calculation should be added in pay method.

Java 8  using Fluent API. 

Java Concurrency CountDownLatch

CountDown Latch

In this article we will discuss about CountDownLatch . Same is introduced in java 5.
CountDownLatch works very same way as Object’s wait() and notify() does ,but it is a Toplevel class
And very easy to use than wait/notify.

 CountDownLatch VS wait()/ notify()





Spurious Wake up:




look above code snippet, in case of spurious wake up, Thread goes to JobQueue.remove(i) line as it is suddenly wakes up due to spurious phenomena, but there is no job in queue (as producers does not produce a job), so above code throws NoSuchElementException.

To solve this problem, we are going to make a slight change in above code.
put, while(JobQueue.empty()) instead of ,if(JobQueue.empty()) , Now in case of spurious wakes up ,while(JobQueue.empty())  always holds true as producer does not produces a job and put the same in JobQueue.

While using CountDownlatch, developers don’t have to bother about spurious wake-up as CountDownlatch implements on gate principle.
CountDownlatch initializes with a positive number and blocking thread has to wait until this number becomes  Zero.   If a Spurious wake up occurs and count is greater than zero obviously blocking thread must has to wait as count is not zero, blocking threads only got chance, when running thread invoke countdown() and count decreases to zero.

Important Methods of CountDownlatch:

CountDownLatch has one disadvantage ,once it’s counter  is zero it can’t be reset again .For reset one should use CyclicBarrier.

Example: In a Restaurant, Food only be served once same is prepared. Preparing and Serving foods are two different services but they have to maintain a sequence, unless food is prepared it can’t be served.

We try to solve this problem by CountDownlatch.

Code :
package com.example.concurrency.countdownlatch;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PrepareServeProblem {
      
       public static void main(String[] args) {
             
              ExecutorService service = Executors.newFixedThreadPool(2);
              CountDownLatch latch = new CountDownLatch(1);
             
              Runnable prepareService = new Runnable()
              {
                     public void run()
                     {
                           try {
                                  Thread.sleep(1000);
                           } catch (InterruptedException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                           }
                           System.out.println("Preparing Food");
                           latch.countDown();
                     }
              };
             
             
              Runnable serveService = new Runnable()
              {
                     public void run()
                     {
                           try {
                                  latch.await();
                                  System.out.println("wating for prepareService to finish");
                           } catch (InterruptedException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                           }
                           System.out.println("Serving the Food");
                          
                     }
              };
             
              service.execute(serveService);
              service.execute(prepareService);
             
             
       }

}

Output:
Preparing Food
wating for prepareService to finish
Serving the Food