Skip to the content.

Design patterns

-

What we’ll cover

-

Creational Patterns

-

Two Recurring Themes of Creational Patterns

  1. They encapsulate knowledge about which concrete classes the system uses
    • Abstracts the instantiation process
  2. Hide how instances of classes are created and put together
    • Helps make a system independent of how its objects are created, composed, or represented</li>

-

Singleton Pattern

-

Brief Example

public class GoFishGame {
  private List<GoFishPlayer> playerList;

  public void addNewPlayer() {
    String userPrompt = "What is your profile ID?";
    IOConsole console = new IOConsole();
    ProfileManager profileManager = ProfileManager.getInstance();

    Integer profileId = console.getIntegerInput(userPrompt);
    Profile profile = profileManager.getById(profileId);
    GoFishPlayer player = new GoFishPlayer(profile);
    playerList.add(player);
  }
}

-

Implementing a Singleton

-

Eager Initialization

-

Eager Initialization: Example

public class ProfileManager implements Container<Profile> {
  private static final ProfileManager instance = new ProfileManager();
  private final Group<Profile> profileContainer;

  private ProfileManager(){ this.profileContainer = new Group<>(); }

  public static ProfileManager getInstance(){ return instance; }
  public void add(Profile profile) { profileContainer.add(profile); }
  public void remove(Profile profile) { profileContainer.remove(profile); }
  public Profile getById(Long id) { profileContainer.getById(id);}
}

-

Accessing Eager Initialization singleton

public class GoFishGame {
  private List<GoFishPlayer> playerList;

  public void addNewPlayer() {
    String userPrompt = "What is your profile ID?";
    IOConsole console = new IOConsole();

    // static `getInstance` access
    ProfileManager profileManager = ProfileManager.getInstance();

    Integer profileId = console.getIntegerInput(userPrompt);
    Profile profile = profileManager.getById(profileId);
    GoFishPlayer player = new GoFishPlayer(profile);
    playerList.add(player);
  }
}

-

Lazy Initialization: Example

public class ProfileManager implements Container<Profile> {
  private static final ProfileManager instance;
  private final Container<Profile> profileContainer;

  private ProfileManager(){ this.profileContainer = new Container<>(); }

  public static ProfileManager getInstance(){
    if(instance == null) {
      instance = new ProfileManager();
    }
    return instance;
  }
  public void add(Profile profile) { profileContainer.add(profile); }
  public void remove(Profile profile) { profileContainer.remove(profile); }
  public Profile getById(Long id) { return profileContainer.getById(id);}
}

-

Accessing Lazy Initialization singleton

public class GoFishGame {
  private List<GoFishPlayer> playerList;

  public void addNewPlayer() {
    String userPrompt = "What is your profile ID?";
    IOConsole console = new IOConsole();

    // static `getInstance` access
    ProfileManager profileManager = ProfileManager.getInstance();

    Integer profileId = console.getIntegerInput(userPrompt);
    Profile profile = profileManager.getById(profileId);
    GoFishPlayer player = new GoFishPlayer(profile);
    playerList.add(player);
  }
}

-

Enum Singleton: Example

public enum ProfileManager implements Container<Profile> {
  INSTANCE;
  private final Container<Profile> profileContainer;

  private ProfileManager(){ this.profileContainer = new Container<>(); }

  public void add(Profile profile) { profileContainer.add(profile); }
  public void remove(Profile profile) { profileContainer.remove(profile); }
  public Profile getById(Long id) { return profileContainer.getById(id);}
}

-

Accessing Enum singleton

public class GoFishGame {
  private List<GoFishPlayer> playerList;

  public void addNewPlayer() {
    String userPrompt = "What is your profile ID?";
    IOConsole console = new IOConsole();

    // static `INSTANCE` access
    ProfileManager profileManager = ProfileManager.INSTANCE;

    Integer profileId = console.getIntegerInput(userPrompt);
    Profile profile = profileManager.getById(profileId);
    GoFishPlayer player = new GoFishPlayer(profile);
    playerList.add(player);
  }
}

-

Creational Patterns: Factory

-

Factory Methods; Example 1

public void demo() {
  String string = "Hello world";
  string.replaceAll("Hello", "");
  System.out.println(string);
}

Output

Hello world

-

Factory Methods; Example 2

public class PersonFactory {
  // factory method
  public Person createRandomPerson() {
    String name = RandomUtils.createString('a', 'z', 5);
    return createRandomlyAgedPerson(name);
  }

  // factory method
  public Person createRandomlyAgedPerson(String name) {
    Integer randomAge = RandomUtils.createInteger(0, 100);
    return new Person(name, randomAge);
  }
}

-

Abstract Factory Pattern Example

-

Issues with Factory Pattern

-

Creational Patterns: Builder

-

Builder Pattern

-

Brief Example, Part 1

public class License {
    String name, addressLine1, addressLine2, city, state;
    Date birthDate, issuedDate, expirationDate;
    Integer licenseNumber, zipcode;

    public License(String name, String addressLine1,
                   String addressLine2, String city,
                   String state, Date birthDate,
                   Date issuedDate, Date expirationDate,
                   Integer licenseNumber, Integer zipcode) {
       // definition omitted
    }
}

-

Brief Example, Part 2

public void demo() {
		License license = new License(
						"John",
						"123 Square Lane",
						null,
						"Milford",
						"Delaware",
						new Date(),
						null,
						null,
						1238913312,
						19720);
}

-

Brief Example, Part 3

public class LicenseBuilder {
    private String name;
    private String addressLine1;
    private String addressLine2;
    // ... more fields

    public LicenseBuilder setName(String name) {
        this.name = name;
        return this;
    }

		// ... more setters
    public License build() {
        return new License(name, addressLine1, addressLine2, city, state, birthDate, issuedDate, expirationDate, licenseNumber, zipcode);
    }
}

-

Constructing a License with LicenseBuilder

public void demo() {
		License license = new LicenseBuilder()
            .setBirthDate(new Date())
            .setName("John")
            .setAddressLine1("123 Square Lane")
            .setCity("Milford")
            .setState("Delaware")
            .setZipCode(19720)
            .setLicenseNumber(1238913312)
            .build();
}

-

Image of Puppies