Download StudentBuilderDemo.java
1: // Student.java - A demo of using optional constructor arguments by 2: // using the "constructor builder pattern". Student objects represent 3: // students enrolled in a college course and have many attributes. 4: // With more than a few, multiple constructors become hard to use well. 5: // The alternative of the "JavaBean" pattern (of providing "getters" and 6: // "setters" for each attribute) allows for inconsistant states and 7: // prevents immutable objects (desirable when possible). 8: // 9: // The builder "helper" class is nested within the Student class, 10: // to allow it access to the single private Student constructor. The 11: // only way to construct a Student is to create a Builder, set the 12: // optional values, then call Builder.build method. 13: // 14: // Also notice how each method of the builder returns the (modified) 15: // builder. This allows the method calls to be "chained", simulating 16: // named optional parameters. 17: // (Validity checking of arguments and other details omitted for clarity.) 18: // 19: // Written 5/2008 by Wayne Pollock, Tampa Florida USA. All Rights Reserved. 20: 21: import java.util.Date; 22: 23: class Student 24: { 25: private static int nextStudentID; 26: 27: static { 28: // Typically fetched from a DB at application (JVM) startup: 29: // nextStudentID = ...; 30: nextStudentID = 1; // For demo purposes 31: } 32: 33: // Add a shutdown hook to save the current value of nextStudentID 34: // to the DB when the application (the JVM) exits: 35: // ... 36: 37: private int studentID; 38: private String lastName; 39: private String firstName; 40: private String address; 41: private String homePhone; 42: private int level; // 1 = freshman, ... 43: private Date enrolled; 44: private char gender; // 'M' or 'F', 'U' = unknown 45: // ... 46: 47: // Single private Student constructor: 48: private Student ( Builder builder ) 49: { 50: studentID = builder.studentID; 51: lastName = builder.lastName; 52: firstName = builder.firstName; 53: address = builder.address; 54: homePhone = builder.homePhone; 55: level = builder.level; 56: enrolled = builder.enrolled; 57: gender = builder.gender; 58: } 59: 60: // Nested class: 61: public static class Builder 62: { 63: // Required Parameters: 64: private final int studentID; 65: private String lastName; 66: 67: // Optional Parameters (initialized to default values): 68: private String firstName = ""; 69: private String address = "unknown"; 70: private String homePhone = "unknown"; 71: private int level = 1; 72: private Date enrolled = new Date(); 73: private char gender = 'U'; 74: 75: // Public builder constructor, with required parameter: 76: public Builder ( String lastName ) 77: { this.studentID = nextStudentID; 78: ++nextStudentID; 79: this.lastName = lastName; 80: } 81: 82: // Public builder methods for optional paramerers (simulates 83: // named parameters): 84: public Builder firstName ( String arg ) 85: { firstName = arg; return this; } 86: public Builder address ( String arg ) 87: { address = arg; return this; } 88: public Builder homePhone ( String arg ) 89: { homePhone = arg; return this; } 90: public Builder level ( int arg ) 91: { level = arg; return this; } 92: public Builder enrolled ( Date arg ) 93: { enrolled = arg; return this; } 94: public Builder gender ( char arg ) 95: { gender = arg; return this; } 96: 97: // Public build method, called after setting the optional fields: 98: public Student build () { return new Student( this ); } 99: } 100: 101: // public Student methods go here: 102: // ... 103: 104: // Display all fields & values (for demo purposes): 105: public String toString () { 106: return "studentID: " + studentID + 107: "\nlastName: " + lastName + 108: "\nfirstName: " + firstName + 109: "\naddress: " + address + 110: "\nhomePhone: " + homePhone + 111: "\nlevel: " + level + 112: "\nenrolled: " + enrolled + 113: "\ngender: " + gender; 114: } 115: } 116: 117: // Sample use (all the above complexity is so we can do this): 118: public class StudentBuilderDemo 119: { 120: public static void main ( String [] args ) { 121: Student s = new Student.Builder("Piffl").firstName("Hymie"). 122: level(4).build(); 123: // ... 124: System.out.println( s ); // For demo purposes 125: } 126: }