StudentBuilderDemo.java

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: // Updated 3/2021: Replaced mutable Date with immutable LocalDate.
 21: 
 22: import java.time.*;
 23: 
 24: class Student
 25: {
 26:    private static int nextStudentID;
 27: 
 28:    static {
 29:       // Typically fetched from a DB at application (JVM) startup:
 30:       // nextStudentID = ...;
 31:       nextStudentID = 1;  // For demo purposes
 32:    }
 33: 
 34:    // Add a shutdown hook to save the current value of nextStudentID
 35:    // to the DB when the application (the JVM) exits:
 36:    // ...
 37: 
 38:    private int studentID;
 39:    private String lastName;
 40:    private String firstName;
 41:    private String address;
 42:    private String homePhone;
 43:    private int level;  // 1 = freshman, ...
 44:    private LocalDate enrolled;
 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:    }
 58: 
 59:    // Nested class:
 60:    public static class Builder
 61:    {
 62:       // Required Parameters:
 63:       private final int studentID;
 64:       private String lastName;
 65: 
 66:       // Optional Parameters (initialized to default values):
 67:       private String firstName = "";
 68:       private String address = "unknown";
 69:       private String homePhone = "unknown";
 70:       private int level = 1;
 71:       private LocalDate enrolled = LocalDate.now();
 72: 
 73:       // Public builder constructor, with required parameter:
 74:       public Builder ( String lastName )
 75:       {  this.studentID = nextStudentID;
 76:          ++nextStudentID;
 77:          this.lastName = lastName;
 78:       }
 79: 
 80:       // Public builder methods for optional parameters (simulates
 81:       // named parameters):
 82:       public Builder firstName ( String arg )
 83:       {  firstName = arg; return this; }
 84:       public Builder address ( String arg )
 85:       {  address = arg; return this; }
 86:       public Builder homePhone ( String arg )
 87:       {  homePhone = arg; return this; }
 88:       public Builder level ( int arg )
 89:       {  level = arg; return this; }
 90:       public Builder enrolled ( LocalDate arg )
 91:       {  enrolled = arg; return this; }
 92: 
 93:       // Public build method, called after setting the optional fields:
 94:       public Student build () { return new Student( this ); }
 95:    }
 96: 
 97:    // public Student methods go here:
 98:    // ...
 99: 
100:    // Display all fields & values (for demo purposes):
101:    public String toString () {
102:       return "studentID: " + studentID +
103:         "\nlastName: " + lastName +
104:         "\nfirstName: " + firstName +
105:         "\naddress: " + address +
106:         "\nhomePhone: " + homePhone +
107:         "\nlevel: " + level +
108:         "\nenrolled: " + enrolled;
109:    }
110: }
111: 
112: // Sample use (all the above complexity is so we can do this):
113: public class StudentBuilderDemo
114: {
115:   public static void main ( String [] args ) {
116:     Student s = new Student.Builder("Piffl").firstName("Hymie").
117:        level(4).build();
118:     // ...
119:     System.out.println( s );  // For demo purposes
120:   }
121: }