* Fix languages * Missed change for version number * Add language field for presentation * Revert change in README for double buffer Co-authored-by: Jackie Nim <=>
		
			
				
	
	
		
			140 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | ||
| layout: pattern
 | ||
| title: Parameter Object
 | ||
| folder: parameter-object
 | ||
| permalink: /patterns/parameter-object/
 | ||
| categories: Behavioral
 | ||
| language: en
 | ||
| tags:
 | ||
|  - Extensibility
 | ||
| ---
 | ||
| 
 | ||
| ## Intent
 | ||
| 
 | ||
| The syntax of Java language doesn’t allow you to declare a method with a predefined value
 | ||
| for a parameter. Probably the best option to achieve default method parameters in Java is
 | ||
| by using the method overloading. Method overloading allows you to declare several methods
 | ||
| with the same name but with a different number of parameters. But the main problem with
 | ||
| method overloading as a solution for default parameter values reveals itself when a method
 | ||
| accepts multiple parameters. Creating an overloaded method for each possible combination of
 | ||
| parameters might be cumbersome. To deal with this issue, the Parameter Object pattern is used.
 | ||
| 
 | ||
| ## Explanation
 | ||
| 
 | ||
| The Parameter Object is simply a wrapper object for all parameters of a method.
 | ||
| It is nothing more than just a regular POJO. The advantage of the Parameter Object over a
 | ||
| regular method parameter list is the fact that class fields can have default values.
 | ||
| Once the wrapper class is created for the method parameter list, a corresponding builder class
 | ||
| is also created. Usually it's an inner static class. The final step is to use the builder
 | ||
| to construct a new parameter object. For those parameters that are skipped,
 | ||
| their default values are going to be used.
 | ||
| 
 | ||
| 
 | ||
| **Programmatic Example**
 | ||
| 
 | ||
| Here's the simple `SearchService` class where Method Overloading is used to default values here. To use method overloading, either the number of arguments or argument type has to be different.
 | ||
| 
 | ||
| ```java
 | ||
| public class SearchService {
 | ||
|   //Method Overloading example. SortOrder is defaulted in this method
 | ||
|   public String search(String type, String sortBy) {
 | ||
|     return getQuerySummary(type, sortBy, SortOrder.DESC);
 | ||
|   }
 | ||
| 
 | ||
|   /* Method Overloading example. SortBy is defaulted in this method. Note that the type has to be 
 | ||
|   different here to overload the method */
 | ||
|   public String search(String type, SortOrder sortOrder) {
 | ||
|     return getQuerySummary(type, "price", sortOrder);
 | ||
|   }
 | ||
| 
 | ||
|   private String getQuerySummary(String type, String sortBy, SortOrder sortOrder) {
 | ||
|     return "Requesting shoes of type \"" + type + "\" sorted by \"" + sortBy + "\" in \""
 | ||
|         + sortOrder.getValue() + "ending\" order...";
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| ```
 | ||
| 
 | ||
| Next we present the `SearchService` with `ParameterObject` created with Builder pattern.
 | ||
| 
 | ||
| ```java
 | ||
| public class SearchService {
 | ||
| 
 | ||
|   /* Parameter Object example. Default values are abstracted into the Parameter Object 
 | ||
|   at the time of Object creation */
 | ||
|   public String search(ParameterObject parameterObject) {
 | ||
|     return getQuerySummary(parameterObject.getType(), parameterObject.getSortBy(),
 | ||
|         parameterObject.getSortOrder());
 | ||
|   }
 | ||
|   
 | ||
|   private String getQuerySummary(String type, String sortBy, SortOrder sortOrder) {
 | ||
|     return "Requesting shoes of type \"" + type + "\" sorted by \"" + sortBy + "\" in \""
 | ||
|         + sortOrder.getValue() + "ending\" order...";
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| public class ParameterObject {
 | ||
|   public static final String DEFAULT_SORT_BY = "price";
 | ||
|   public static final SortOrder DEFAULT_SORT_ORDER = SortOrder.ASC;
 | ||
| 
 | ||
|   private String type;
 | ||
|   private String sortBy = DEFAULT_SORT_BY;
 | ||
|   private SortOrder sortOrder = DEFAULT_SORT_ORDER;
 | ||
| 
 | ||
|   private ParameterObject(Builder builder) {
 | ||
|     type = builder.type;
 | ||
|     sortBy = builder.sortBy != null && !builder.sortBy.isBlank() ? builder.sortBy : sortBy;
 | ||
|     sortOrder = builder.sortOrder != null ? builder.sortOrder : sortOrder;
 | ||
|   }
 | ||
| 
 | ||
|   public static Builder newBuilder() {
 | ||
|     return new Builder();
 | ||
|   }
 | ||
| 
 | ||
|   //Getters and Setters...
 | ||
| 
 | ||
|   public static final class Builder {
 | ||
| 
 | ||
|     private String type;
 | ||
|     private String sortBy;
 | ||
|     private SortOrder sortOrder;
 | ||
| 
 | ||
|     private Builder() {
 | ||
|     }
 | ||
| 
 | ||
|     public Builder withType(String type) {
 | ||
|       this.type = type;
 | ||
|       return this;
 | ||
|     }
 | ||
| 
 | ||
|     public Builder sortBy(String sortBy) {
 | ||
|       this.sortBy = sortBy;
 | ||
|       return this;
 | ||
|     }
 | ||
| 
 | ||
|     public Builder sortOrder(SortOrder sortOrder) {
 | ||
|       this.sortOrder = sortOrder;
 | ||
|       return this;
 | ||
|     }
 | ||
| 
 | ||
|     public ParameterObject build() {
 | ||
|       return new ParameterObject(this);
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| ```
 | ||
| 
 | ||
| ## Class diagram
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ## Applicability
 | ||
| 
 | ||
| This pattern shows us the way to have default parameters for a method in Java as the language doesn't default parameters feature out of the box. 
 | ||
| 
 | ||
| ## Credits
 | ||
| 
 | ||
| - [Does Java have default parameters?](http://dolszewski.com/java/java-default-parameters)
 |