Skip to content

Instantly share code, notes, and snippets.

@swlaschin
Created February 14, 2014 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swlaschin/9009343 to your computer and use it in GitHub Desktop.
Save swlaschin/9009343 to your computer and use it in GitHub Desktop.
// ==============================
// This gist contains the code from
// http://programmers.stackexchange.com/questions/228939/how-to-improve-upon-blochs-builder-pattern-to-make-it-more-appropriate-for-use
//
// Compare with the functional version at https://gist.github.com/swlaschin/9008814
// ==============================
// ==========================================
// UserConfig.java
// ==========================================
import java.util.regex.Pattern;
/**
<P>Information about a user -- <I>[builder: UserConfig_Cfg]</I></P>
<P>Validation of all fields occurs in this classes constructor. However, each validation requirement is document only in the builder's setter functions.</P>
<P>{@code java xbn.z.xmpl.lang.builder.finalv.UserConfig}</P>
**/
public class UserConfig {
public static final void main(String[] igno_red) {
UserConfig uc = new UserConfig_Cfg("Kermit").age(50).favoriteColor("green").build();
System.out.println(uc);
}
private final String sName ;
private final int iAge ;
private final String sFavColor;
/**
<P>Create a new instance. This sets and validates all fields.</P>
@param uc_f May not be {@code null}.
**/
public UserConfig(UserConfig_Fieldable uc_f) {
//transfer
try {
sName = uc_f.getName();
} catch(NullPointerException rx) {
throw new NullPointerException("uc_f");
}
iAge = uc_f.getAge();
sFavColor = uc_f.getFavoriteColor();
//validate
try {
if(!Pattern.compile("\\w+").matcher(sName).matches()) {
throw new IllegalArgumentException("uc_f.getName() (\"" + sName + "\") may not be empty, and must contain only letters digits and underscores.");
}
} catch(NullPointerException rx) {
throw new NullPointerException("uc_f.getName()");
}
if(iAge < 0) {
throw new IllegalArgumentException("uc_f.getAge() (" + iAge + ") is less than zero.");
}
try {
if(!Pattern.compile("(?:red|blue|green|hot pink)").matcher(sFavColor).matches()) {
throw new IllegalArgumentException("uc_f.getFavoriteColor() (\"" + uc_f.getFavoriteColor() + "\") is not red, blue, green, or hot pink.");
}
} catch(NullPointerException rx) {
throw new NullPointerException("uc_f.getFavoriteColor()");
}
}
//getters...START
/**
<P>The user's name.</P>
@return A non-{@code null}, non-empty string.
@see UserConfig_Cfg#UserConfig_Cfg(String)
@see #getAge()
@see #getFavoriteColor()
**/
public String getName() {
return sName;
}
/**
<P>The user's age.</P>
@return A number greater-than-or-equal-to zero.
@see UserConfig_Cfg#age(int)
@see #getName()
**/
public int getAge() {
return iAge;
}
/**
<P>The user's favorite color.</P>
@return A non-{@code null}, non-empty string.
@see UserConfig_Cfg#age(int)
@see #getName()
**/
public String getFavoriteColor() {
return sFavColor;
}
//getters...END
public String toString() {
return "getName()=" + getName() + ", getAge()=" + getAge() + ", getFavoriteColor()=" + getFavoriteColor();
}
}
// ==========================================
// UserConfig_Fieldable.java
// ==========================================
/**
<P>Required by the {@link UserConfig} {@code UserConfig#UserConfig(UserConfig_Fieldable) constructor}.</P>
**/
public interface UserConfig_Fieldable {
String getName();
int getAge();
String getFavoriteColor();
}
// ==========================================
// UserConfig_Cfg.java
// ==========================================
import java.util.regex.Pattern;
/**
<P>Builder for {@link UserConfig}.</P>
<P>Validation of all fields occurs in the <CODE>UserConfig</CODE> constructor. However, each validation requirement is document only in this classes setter functions.</P>
**/
public class UserConfig_Cfg implements UserConfig_Fieldable {
public String sName ;
public int iAge ;
public String sFavColor;
/**
<P>Create a new instance with the user's name.</P>
@param s_name May not be {@code null} or empty, and must contain only letters, digits, and underscores. Get with {@code UserConfig#getName() getName()}{@code ()}*.
**/
public UserConfig_Cfg(String s_name) {
sName = s_name;
}
//self-returning setters...START
/**
<P>Set the user's age.</P>
@param i_age May not be less than zero. Get with {@code UserConfig#getName() getName()}{@code ()}*.
@see #favoriteColor(String)
**/
public UserConfig_Cfg age(int i_age) {
iAge = i_age;
return this;
}
/**
<P>Set the user's favorite color.</P>
@param s_color Must be {@code "red"}, {@code "blue"}, {@code green}, or {@code "hot pink"}. Get with {@code UserConfig#getName() getName()}{@code ()}*.
@see #age(int)
**/
public UserConfig_Cfg favoriteColor(String s_color) {
sFavColor = s_color;
return this;
}
//self-returning setters...END
//getters...START
public String getName() {
return sName;
}
public int getAge() {
return iAge;
}
public String getFavoriteColor() {
return sFavColor;
}
//getters...END
/**
<P>Build the UserConfig, as configured.</P>
@return <CODE>(new {@link UserConfig#UserConfig(UserConfig_Fieldable) UserConfig}(this))</CODE>
**/
public UserConfig build() {
return (new UserConfig(this));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment