/home/wpollock1/public_html/AJava/StudentBuilderDemo.java

// Student.java - A demo of using optional constructor arguments by
// using the "constructor builder pattern".  Student objects represent
// students enrolled in a college course and have many attributes.
// With more than a few, multiple constructors become hard to use well.
// The alternative of the "JavaBean" pattern (of providing "getters" and
// "setters" for each attribute) allows for inconsistant states and
// prevents immutable objects (desirable when possible).
//
// The builder "helper" class is nested within the Student class,
// to allow it access to the single private Student constructor.  The
// only way to construct a Student is to create a Builder, set the
// optional values, then call Builder.build method.
//
// Also notice how each method of the builder returns the (modified)
// builder.  This allows the method calls to be "chained", simulating
// named optional parameters.
// (Validity checking of arguments and other details omitted for clarity.)
//
// Written 5/2008 by Wayne Pollock, Tampa Florida USA.  All Rights Reserved.
// Updated 3/2021: Replaced mutable Date with immutable LocalDate.

import java.time.*;

class Student
{
   private static int nextStudentID;

   static {
      // Typically fetched from a DB at application (JVM) startup:
      // nextStudentID = ...;
      nextStudentID = 1;  // For demo purposes
   }

   // Add a shutdown hook to save the current value of nextStudentID
   // to the DB when the application (the JVM) exits:
   // ...

   private int studentID;
   private String lastName;
   private String firstName;
   private String address;
   private String homePhone;
   private int level;  // 1 = freshman, ...
   private LocalDate enrolled;
   // ...

   // Single private Student constructor:
   private Student ( Builder builder )
   {
      studentID = builder.studentID;
      lastName  = builder.lastName;
      firstName = builder.firstName;
      address   = builder.address;
      homePhone = builder.homePhone;
      level     = builder.level;
      enrolled  = builder.enrolled;
   }

   // Nested class:
   public static class Builder
   {
      // Required Parameters:
      private final int studentID;
      private String lastName;

      // Optional Parameters (initialized to default values):
      private String firstName = "";
      private String address = "unknown";
      private String homePhone = "unknown";
      private int level = 1;
      private LocalDate enrolled = LocalDate.now();

      // Public builder constructor, with required parameter:
      public Builder ( String lastName )
      {  this.studentID = nextStudentID;
         ++nextStudentID;
         this.lastName = lastName;
      }

      // Public builder methods for optional parameters (simulates
      // named parameters):
      public Builder firstName ( String arg )
      {  firstName = arg; return this; }
      public Builder address ( String arg )
      {  address = arg; return this; }
      public Builder homePhone ( String arg )
      {  homePhone = arg; return this; }
      public Builder level ( int arg )
      {  level = arg; return this; }
      public Builder enrolled ( LocalDate arg )
      {  enrolled = arg; return this; }

      // Public build method, called after setting the optional fields:
      public Student build () { return new Student( this ); }
   }

   // public Student methods go here:
   // ...

   // Display all fields & values (for demo purposes):
   public String toString () {
      return "studentID: " + studentID +
        "\nlastName: " + lastName +
        "\nfirstName: " + firstName +
        "\naddress: " + address +
        "\nhomePhone: " + homePhone +
        "\nlevel: " + level +
        "\nenrolled: " + enrolled;
   }
}

// Sample use (all the above complexity is so we can do this):
public class StudentBuilderDemo
{
  public static void main ( String [] args ) {
    Student s = new Student.Builder("Piffl").firstName("Hymie").
       level(4).build();
    // ...
    System.out.println( s );  // For demo purposes
  }
}