Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Maneesh Chauhan committed Oct 21, 2015
2 parents ab95e68 + b11f5f2 commit cb61a65
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 0 deletions.
124 changes: 124 additions & 0 deletions EffectiveJava/src/com/manchau/creational/ObjectBuilderDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.manchau.creational;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;


/***
*
* @author Maneesh
* Item2: Instead of having a telescope constructor pattern where we have multiple
* constructors, each with a different number of formal parameters, we should implement
* a static builder class for such a class.
*/


class EmployeeInformation {
private final String name;
private final Date dateOfBirth;
private final Date dateOfJoining;
private String jobTitle;
private String department;

public EmployeeInformation(EmployeeInformationBuilder builder) {
this.name = builder.getName();
this.dateOfBirth = builder.getDateOfBirth();
this.dateOfJoining = builder.getDateOfJoining();
this.jobTitle = builder.getJobTitle();
this.department = builder.getDepartment();
}
public String getName() {
return name;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public Date getDateOfJoining() {
return dateOfJoining;
}
public String getJobTitle() {
return jobTitle;
}
public String getDepartment() {
return department;
}

// Static Builder
public static class EmployeeInformationBuilder {
private final String name;
private final Date dateOfBirth;
private final Date dateOfJoining;
private String jobTitle = "Employee";
private String department = "Office";
//constructor
public EmployeeInformationBuilder( String name, Date dateOfBirth, Date dateOfJoining) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.dateOfJoining = dateOfJoining;
}
// setters
public EmployeeInformationBuilder setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
return this;
}
public EmployeeInformationBuilder setDepartment(String department) {
this.department = department;
return this;
}

// builder
public EmployeeInformation build() {
return new EmployeeInformation(this);
}

// getters
public String getName() {
return name;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public Date getDateOfJoining() {
return dateOfJoining;
}
public String getJobTitle() {
return jobTitle;
}
public String getDepartment() {
return department;
}
}

public void display() {
System.out.println("Employee Name: " + this.name);
System.out.println("Date Of Birth: " + this.dateOfBirth);
System.out.println("Joined On: " + this.dateOfJoining);
System.out.println("Job Title: " + this.jobTitle);
System.out.println("Unit: " + this.department);
}
}


public class ObjectBuilderDemo {

public static void main(String[] args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
EmployeeInformation.EmployeeInformationBuilder infoBuilder;
try {
infoBuilder = new EmployeeInformation.EmployeeInformationBuilder("John Doe",
dateFormat.parse("1971-01-01"),
dateFormat.parse("1995-08-02"));
infoBuilder.setJobTitle("Software Developer").setDepartment("San Diego");

EmployeeInformation info = infoBuilder.build();
info.display();

} catch (ParseException e) {
Logger logger = Logger.getLogger("ObjectBuilderDemo");
logger.log(Level.SEVERE, "Improper date format", e);
}
}
}
99 changes: 99 additions & 0 deletions EffectiveJava/src/com/manchau/creational/StaticFactoryDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.manchau.creational;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/***
*
* @author Maneesh
* Item 1: Consider static factory methods instead of constructors
*
* Why it's a good Idea:
* 1. Declarative of intent and purpose for the constructed object
* 2. Reuse of instance
* 3. Polymorphism and abstraction of underlying implementations
*
* Why not:
* 1. Only having static factory methods prevents sub classing
* - Although it might promote composition instead of inheritance
* 2. In absence of proper nomenclature, these can be confusing for a user
*/

interface ModifierService {
public int doMod(int num);
}
class DoublerService implements ModifierService {
@Override
public int doMod(int num) {
return num*2;
}
}
class SquarerService implements ModifierService {
@Override
public int doMod(int num) {
return num*num;
}
}

interface ModifierServiceProvider {
public ModifierService newModifierService();
}
class SquarerServiceProvider implements ModifierServiceProvider {
private final SquarerService service;
public SquarerServiceProvider() {
service = new SquarerService();
}
@Override
public ModifierService newModifierService() {
return service;
}
}
class DoublerServiceProvider implements ModifierServiceProvider {
private final DoublerService service;
public DoublerServiceProvider() {
service = new DoublerService();
}
@Override
public ModifierService newModifierService() {
return service;
}
}

class ModifierServices {
/* registers service providers by name and provides static factory
methods to get service instances */
private static final Map<String,ModifierServiceProvider> providers =
new ConcurrentHashMap<>();
public static final String DEFAULT_PROVIDER_NAME = "<DEF>";

//Registration API
public static void registerProvider(String name, ModifierServiceProvider provider) {
providers.put(name, provider);
}
//Static factories
public static ModifierService newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static ModifierService newInstance(String id) {
ModifierServiceProvider provider = providers.get(id);
if(provider == null) {
throw new IllegalArgumentException("No provider registered with the name: " + id);
}
return provider.newModifierService();
}
}

public class StaticFactoryDemo {
public static void main(String[] args) {
int i = 10;
String name = "Squarer";
// register service providers
ModifierServices.registerProvider(ModifierServices.DEFAULT_PROVIDER_NAME, new DoublerServiceProvider());
ModifierServices.registerProvider(name, new SquarerServiceProvider());

// retrieve different modifications based on different names of service providers

System.out.println(ModifierServices.newInstance().doMod(i));
System.out.println(ModifierServices.newInstance(name).doMod(i));
}
}

0 comments on commit cb61a65

Please sign in to comment.