Prototype Design Pattern

The Prototype pattern is a Creational Design Pattern that avoids costly creation of objects. The concept of this is to copy an existing object versus creating a new object all together. This is typically done using the clone() method from the Clonable interface. This design pattern is useful when creating objects becomes too costly or they take too much time.

Although you will be creating copies of an object, each instance will be unique. This is what’s called a Deep Copy. A deep copy will return a brand new object to a new instance, rather than a reference to the original object (Shallow Copy).  Shallow Copies are dangerous because you could change the parameters in one object and it would reflect in both the copied and original object. The construction of the objects will be handle by a Registry class.

We will implement a Device example of the Prototype pattern in Java. We will create an abstract class called Device that implements Clonable from the Java API. The DeviceRegistry  class will contain a static method that returns a cloned instance of Device.



1. Create an abstract class called Device. This will contain getters and setters for id and name. This will contain abstract methods powerOn() and addDevice() that will be overridden by sub-classes.

public abstract class Device implements Cloneable {
    private int id;
    private String deviceName;

    abstract void powerOn();
    abstract void addDevice();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDeviceName() {
        return deviceName;
    }

    public void setDeviceName(String deviceName) {
        this.deviceName = deviceName;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}


2. Add sub-classes Iphone and Pixel.

public abstract class Device implements Cloneable {
    private int id;
    private String deviceName;

    abstract void powerOn();
    abstract void addDevice();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDeviceName() {
        return deviceName;
    }

    public void setDeviceName(String deviceName) {
        this.deviceName = deviceName;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}
public class Pixel extends Device {
    @Override
    void powerOn() {
        System.out.println("Powered On Pixel");
    }

    @Override
    void addDevice() {
        System.out.println("Added Pixel Device");
    }
}


3. Create the Registry class that will contain a getDevice() method that will clone the Device object into a new instance.

package Prototype;

import java.util.HashMap;
import java.util.Map;

public class DeviceRegistry {

    private static Map<Integer, Device> devices = new HashMap();

    /**
     * Clones a Device object into a new instance by deviceId.
     *
     * @param deviceId - Id of device we want to clone.
     * @return
     */
    public static Device getDevice(Integer deviceId) {
        Device device = null;
        try {
            device = (Device) (devices.get(deviceId)).clone();
        } catch (CloneNotSupportedException ex) {

        }
        return device;
    }

    /**
     * Loads devices into objects. In a real application we would pull data from a database.
     */
    public static void loadDevices() {
        Iphone iphone = new Iphone();
        iphone.setId(1);
        iphone.setDeviceName("Iphone 8 Plus");
        devices.put(iphone.getId(), iphone);

        Pixel pixel = new Pixel();
        pixel.setId(2);
        pixel.setDeviceName("Google Pixel 4");
        devices.put(pixel.getId(), pixel);
    }
}

4. Create the client class. This will clone a Device instance into Iphone and Pixel.

public class ProtoypeClient {
    public static void main(String[] args) {
        DeviceRegistry.loadDevices();

        Device iphone = DeviceRegistry.getDevice(1);
        System.out.println(iphone);
        System.out.println(iphone.getDeviceName());
        iphone.addDevice();
        iphone.powerOn();
        System.out.println();

        Device pixel = DeviceRegistry.getDevice(2);
        System.out.println(pixel);
        System.out.println(pixel.getDeviceName());
        pixel.addDevice();
        pixel.powerOn();

    }
}
Prototype.Iphone@1b6d3586
Iphone 8 Plus
Added Iphone
Powered On Iphone

Prototype.Pixel@4554617c
Google Pixel 4
Added Pixel Device
Powered On Pixel

Process finished with exit code 0
Advertisement

Abstract Factory Design Pattern In Java

The Abstract Factory design pattern is a creational design pattern that contains a factory class which creates other factories. It is typically called the Factory of factories. There is an abstract Factory class that other factories inherit in order to implement their own factory method. 

A real world example of this would be a Database or Cache implementation. Let’s say you need to make database updates but need to update a SQL Server, MongoDB, and an Oracle database. These would use similar operations but would require a different implantation in order to connect, update, add and delete data from the database. Abstract Factory would come in handy here because you could have separate factories for a relational and non-relational database.

We are going to implement an example of the Abstract Factory Pattern with a Database implementation in Java. We will create an abstract class DatabaseFactory and 2 concrete classes RelationalDBFactory and NonRelationalDBFactory. The DatabaseFactory class will have a static method getFactory()that returns DatabaseFactory. The concrete classes will return a Database object depending on the type. 


1.  Create the abstract class DatabaseFactory. This contains a static method getFactory(String factory) that returns the correct factory object based on the parameter. getDatabase(String database) is an abstract method that the sub-classes will override.

public abstract class DatabaseFactory {

    /**
     * Returns the correct Factory object based on the type.
     * 
     * @param factory
     * @return
     */
    public static DatabaseFactory getFactory(String factory) {
        switch (factory) {
            case "Relational":
                return new RelationalDBFactory();
            case "NonRelational":
                return new NonRelationalDBFactory();
            default:
                return null;
        }
    }

    public abstract Database getDatabase(String database);
}

2. Create the sub-classes RelationalDBFactory and NonRelationalDBFactory. They contain their own version of getDatabase()  that will return a database object such as Mongodb, NoSQL, SQLServer, and MySQL.

public class NonRelationalDBFactory extends DatabaseFactory {

    /**
     * Returns a Database object of either Mongodb or NoSQL which are Non-relational databases.
     * @param database
     * @return
     */
    @Override
    public Database getDatabase(String database) {
        switch (database){
            case "Mongodb":
                return new MongoDB();
            case "NoSQL":
                return new NoSQL();
            default:
                return null;
        }
    }
}
public class RelationalDBFactory extends DatabaseFactory {

    /**
     *  Returns a Database object of either SQLServer or MySQL which are Relational databases.
     *
     * @param database
     * @return
     */
    @Override
    public Database getDatabase(String database) {
        switch (database){
            case "SQLServer":
                return new SQLServer();
            case "MySQL":
                return new MySQL();
            default:
                return null;
        }
    }
}


3. Create a Database interface and 4 sub-classes that implement their own connect(), add(), update(), and delete() methods. We don’t care if they are Relational or Non-relational at this point since the factory classes handle that logic.

public interface Database {
    void connect();
    void add();
    void update();
    void delete();
}
public class MongoDB implements Database {
    @Override
    public void connect() {
        System.out.println("Connected to MongoDB Non-Relational Database!");
    }

    @Override
    public void add() {
        System.out.println("Added data to MongoDB Non-Relational Database!");
    }

    @Override
    public void update() {
        System.out.println("Updated data in MongoDB Non-Relational Database!");
    }

    @Override
    public void delete() {
        System.out.println("Deleted data from MongoDB Non-Relational Database!");
    }
}
public class MySQL implements Database {
    @Override
    public void connect() {
        System.out.println("Connected to MySQL Relational Database!");
    }

    @Override
    public void add() {
        System.out.println("Added data to MySQL Relational Database!");
    }

    @Override
    public void update() {
        System.out.println("Updated data in MySQL Relational Database!");
    }

    @Override
    public void delete() {
        System.out.println("Deleted data from MySQL Relational Database!");
    }
}
public class NoSQL implements Database {
    @Override
    public void connect() {
        System.out.println("Connected to NoSQL Non-Relational Database!");
    }

    @Override
    public void add() {
        System.out.println("Added data to NoSQL Non-Relational Database!");
    }

    @Override
    public void update() {
        System.out.println("Updated data in NoSQL Non-Relational Database!");
    }

    @Override
    public void delete() {
        System.out.println("Deleted data from NoSQL Non-Relational Database!");
    }
}
public class SQLServer implements Database {
    @Override
    public void connect() {
        System.out.println("Connected to SQL Server Database");
    }

    @Override
    public void add() {
        System.out.println("Added data to SQL Server Database!");
    }

    @Override
    public void update() {
        System.out.println("Updated data for SQL Server Database!");
    }

    @Override
    public void delete() {
        System.out.println("Deleted data from SQL Server Database!");
    }
}


4. Now we can create the client class and use our factory implementation. We call the static method getFactory(“Relational”) to retrieve our DatabaseFactory method. Then we get the database object that we want to use, SQLServer and MySQL. We then do the same thing for NonRelational.

public class AbstractFactoryClient {
    public static void main(String[] args) {
        //Returns a Relational DatabaseFactory object.
        DatabaseFactory relationalFactory = DatabaseFactory.getFactory("Relational");

        //Returns a SQLServer Database object.
        Database sqlServer = relationalFactory.getDatabase("SQLServer");
        sqlServer.connect();
        sqlServer.add();
        sqlServer.update();
        sqlServer.delete();
        System.out.println();

        //Returns a SQLServer Database object.
        Database mySql = relationalFactory.getDatabase("MySQL");
        mySql.connect();
        mySql.add();
        mySql.update();
        mySql.delete();
        System.out.println();

        //Returns a Non-Relational DatabaseFactory object.
        DatabaseFactory nonRelationalFactory = DatabaseFactory.getFactory("NonRelational");

        //Returns a Mongodb Database object.
        Database mongoDb = nonRelationalFactory.getDatabase("Mongodb");
        mongoDb.connect();
        mongoDb.add();
        mongoDb.update();
        mongoDb.delete();
        System.out.println();

        //Returns a NoSQL Database object.
        Database noSql = nonRelationalFactory.getDatabase("NoSQL");
        noSql.connect();
        noSql.add();
        noSql.update();
        noSql.delete();
        System.out.println();
    }
}
Connected to SQL Server Database
Added data to SQL Server Database!
Updated data for SQL Server Database!
Deleted data from SQL Server Database!

Connected to MySQL Relational Database!
Added data to MySQL Relational Database!
Updated data in MySQL Relational Database!
Deleted data from MySQL Relational Database!

Connected to MongoDB Non-Relational Database!
Added data to MongoDB Non-Relational Database!
Updated data in MongoDB Non-Relational Database!
Deleted data from MongoDB Non-Relational Database!

Connected to NoSQL Non-Relational Database!
Added data to NoSQL Non-Relational Database!
Updated data in NoSQL Non-Relational Database!
Deleted data from NoSQL Non-Relational Database!


Process finished with exit code 0

Factory design pattern in Java with Example

The Factory pattern is a parameter driven creational design pattern. It is one of the most popular design patterns in Java. The Factory pattern does not expose the object instantiation logic to the client by deferring to the sub classes. All the client knows about is common interface that the factory exposes.

Lets implement an example of the Factory pattern for a simple workout application that lets you create a specific workout. We are going to create a Workout interface that contains a createWorkout() method. We will then create two concrete sub classes that inherit Workout, Upperbody and Lowerbody. We will then create a WorkoutFactory class that will be called from the client main method. WorkoutFactory will instantiate an object for us depending on the parameter that was passed into getWorkout(workoutType).

1. Create the Workout interface.

public interface Workout {
    void createWorkout();
}

2. Create the UpperBody and LowerBody sub classes that inherit Workout.

public class LowerBody implements Workout {

    @Override
    public void createWorkout() {
        System.out.println("Created Lower Body Workout that includes:");
        System.out.println("1. Squat");
        System.out.println("2. Lunges");
        System.out.println("3. Calf raises");
    }
}
public class UpperBody implements Workout {

    @Override
    public void createWorkout() {
        System.out.println("Created Upper Body Workout that includes:");
        System.out.println("1. Bench Press");
        System.out.println("2. Push ups");
        System.out.println("3. Incline Bench Press");
    }
}

3. Create the WorkoutType enum to avoid using hard coded strings.

public enum WorkoutType {

    UPPERBODY, LOWERBODY;
}

4. Create a WorkoutFactory class that will contain a static method getWorkout(workoutType). This will be static so we don’t have to create an instance of WorkoutFactory. Instead, we just reference from the class name in the client. This method will create a object for us based on the parameter that is passed.

public class WorkoutFactory {

    public static Workout getWorkout(WorkoutType workoutType) {
        switch (workoutType) {
            case UPPERBODY: {
                return new UpperBody();
            }
            case LOWERBODY: {
                return new LowerBody();
            }

            default: {
                return null;
            }
        }
    }
}

5. In your client/main method, use the WorkoutFactory class to get the workout based on the WorkoutType. The client only cares about the Workout object and doesn’t directly interface with any sub classes here.

public class Main {

    public static void main(String[] args) {
        //Retreives the UpperBody object
        Workout workout = WorkoutFactory.getWorkout(WorkoutType.UPPERBODY);
        
        //Calls createWorkout from UpperBody
        workout.createWorkout();

        //Retrieves the LowerBody object
        workout = WorkoutFactory.getWorkout(WorkoutType.LOWERBODY);

        //Calls createWorkout from LowerBody
        workout.createWorkout();
    }
}


6. Verify the output.

Created Upper Body Workout that includes:
1. Bench Press
2. Push ups
3. Incline Bench Press
Created Lower Body Workout that includes:
1. Squat
2. Lunges
3. Calf raises

 That’s the basic idea of the Factory pattern. This is a simple example but this pattern can get quite complex in a enterprise size application. This pattern is almost the opposite of the Singleton pattern. Singleton returns the same instance and has no interface or subclasses whereas the Factory pattern returns multiple instances and contains sub classes and interfaces.

Thread Safe Singleton Design Pattern in Java.

Singleton is a Creational Design Pattern that allows you to only have one object at a time. This object will be static, so a new instance won’t be created every time you retrieve the object. In the singleton pattern, we create a getInstance() method that retrieves an instance of the class for you versus creating an object yourself. I will show you a simple example and how to make this example thread safe.

public class SingletonClass {

    //SingletonClass instance is created at compile time
    private static SingletonClass singletonClass = new SingletonClass();

    public double value;

    //Constructor cannot be created directly because it is private
    //value is set to 0 when class is compiled
    private SingletonClass(){
        value = 0;
    }

    //The Client(Main method) will call getInstance() to get the instance instead of creating an object
    public static SingletonClass getInstance(){
        return singletonClass;
    }
}
In the SingletonClass,  we initialize the singletonClass at compile time since we are setting the variable immediately. We have a value that we can update directly since it is a public variable. We made the constructor private so that the class cannot be instantiated from the client program (In our case, the main method below). You can get the SingleClass instance using SingletonClass.getInstance() versus SingletonClass instance = new SingleClass()

Lets look at the main method.

public class Main {
    public static void main(String[] args) {
      
        SingletonClass singletonClass1 = SingletonClass.getInstance();
        singletonClass1.value += 5;

        System.out.println("SingletonClass1 value: " + singletonClass1.value);

        SingletonClass singletonClass2 = SingletonClass.getInstance();
        singletonClass2.value += 5;

        System.out.println("SingletonClass2 value: " + singletonClass2.value);

        SingletonClass singletonClass3 = SingletonClass.getInstance();
        singletonClass3.value += 5;

        System.out.println("SingletonClass2 value: " + singletonClass1.value);

    }
}

Here we instantiated SingletonClass into 3 seperate variables. Since the instance is static, each variable will contain the same instance. As you can see, we use each variable to increment the value by 5. Since it maintains the same instance, it will print out as 5, 10, 15 instead of 5, 5, and 5.

There are 2 potential issues with this code though.

  1. The instance is not lazily loaded. This means that the instance is created at compile time versus when we need to get the instance. When the class is loaded, the instance is created when we initialize the variable. 
    private static SingletonClass singletonClass = new SingletonClass();

We only want to create the instance when we call getInstance() the very first time. Let’s make this change:
public class SingletonClass {

    //SingletonClass instance is initialized to null at compile time
    private static SingletonClass singletonClass = null;

    public double value;

    private SingletonClass(){
        value = 0;
    }

    public static SingletonClass getInstance(){
        //The singletonClass is initialized when we call getInstance() the very first time.
        if (singletonClass == null){
            singletonClass = new SingletonClass();
        }
        return singletonClass;
    }
}
As you can see, we declared the instance as null instead of a new SingletonClass(). Then we add a null check in the getInstance() method. This will only initialize the instance when call getInstance() the first time (when we actually need it).


      2. This class is not thread safe.

This means that if multiple threads are running and want to call getInstance() at the same time. Then there is a chance that 2 threads will get past the null check and singletonClass = new SingletonClass(); will get called twice.

 public static SingletonClass getInstance(){
        //This synchronized block will not allow 2 threads to get inside. One thread will enter the
        //block while the second thread waits for it to complete.
        if(singletonClass == null){
            synchronized (SingletonClass.class){
                if (singletonClass == null){
                    singletonClass = new SingletonClass();
                }
            }
        }
        return singletonClass;
    }

Here we added a synchronized block that will only allow 1 thread in at a time. 1 thread will wait while another is in the block, checks if the instance is null, and exits. I added a separate null check inside because 2 threads could get past the null check the first time getInstance is called. We also don’t add synchronized outside the null check because we would only have one thread checking if it’s null at a time. This would be detrimental to performance.

Builder design pattern in Java with example.

The Builder design pattern is a creational pattern that helps limit an objects complexity. This helps immensely with immutable objects with tons of properties in your application. Immutable objects are objects that don’t change, once you create them, you can’t change them. A immutable Java object must have private final fields. You would also instantiate the object and provide all of the properties in the constructor. This means you won’t use setters to set the properties in the object. This becomes a problem when you have multiple properties and only a few are required. Lets look at a quick example.

Say you have an Employee class with five properties (id, firstName, lastName, title, birthdate) in which you want immutable. Let’s also say that you can instantiate an Employee object while only specifying the id. This would require two constructors, one that takes in all of the properties and one that takes in the id only. This can go on and can get quite messy, especially when more properties are added to the Employee object

This is when the Builder design pattern comes in handy. Lets convert this class into a builder class in steps.

public class Employee {
    
    //properties that are only accessible within the Employee class
    private final int id;
    private final String firstName;
    private final String lastName;
    private final String title;
    private final String birthdate;

    //Constructor that takes in an id only. We still have to set the other properties.
    public Employee(int id){
        this.id = id;
        this.firstName = "";
        this.lastName = "";
        this.title = "";
        this.birthdate = "";
    }
    
    //Constructor that takes in id, firstname, and lastname
    public Employee(int id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.title = "";
        this.birthdate = "";
    }

    //Constructor that takes in all properties.
    public Employee(int id, String firstName, String lastName, String title, String birthDate) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.title = title;
        this.birthdate = birthDate;
    }
}

1. Let’s remove the constructors except for the main constructor that takes in a Builder object and assign the variables like so. The builder object will contain all of the properties in the Employee which we will create next. We will also make the constructor private.

public class Employee {

    private final int id;
    private final String firstName;
    private final String lastName;
    private final String title;
    private final String birthdate;

    private Employee(Builder builder) {
        this.id = builder.id;
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.title = builder.title;
        this.birthdate = builder.birthDate;
    }
}

2. Add a static inner class within Employee called Builder. Add all the properties and only make the id final because it will be set in the constructor. We then create setters within the builder class that we can only set when we create the object, I will demonstrate that shortly. The build() method will return the Employee object that we put together.

public class Employee {

    private final int id;
    private final String firstName;
    private final String lastName;
    private final String title;
    private final String birthdate;

    private Employee(Builder builder) {
        this.id = builder.id;
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.title = builder.title;
        this.birthdate = builder.birthDate;
    }

    public static class Builder {
        private final int id;
        private String firstName;
        private String lastName;
        private String title;
        private String birthdate;

        public Builder(int id) {
            this.id = id;
        }

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setBirthDate(String birthDate) {
            this.birthdate = birthDate;
            return this;
        }

        public Employee build() {
            return new Employee(this);
        }
    }
}

3. Add your getters to the Employee class so you can access any of the properties.

public class Employee {

    private final int id;
    private final String firstName;
    private final String lastName;
    private final String title;
    private final String birthdate;

    private Employee(Builder builder) {
        this.id = builder.id;
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.title = builder.title;
        this.birthdate = builder.birthDate;
    }

    public int getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getTitle() {
        return title;
    }

    public String getBirthdate() {
        return birthdate;
    }

    public static class Builder {
        private final int id;
        private String firstName;
        private String lastName;
        private String title;
        private String birthDate;

        public Builder(int id) {
            this.id = id;
        }

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setBirthDate(String birthDate) {
            this.birthDate = birthDate;
            return this;
        }

        public Employee build() {
            return new Employee(this);
        }
    }
}


4. Now lets build your objects! In the main method, create new Employee objects like so. You will build the Employee objects at one time and set whatever properties you want. The only required property is the id and that will be passed into the constructor. .build() will return the Employee object that you created! Once you create your employee object, you will not be able to set properties which makes it immutable!

public class Main {

    public static void main(String[] args) {
        Employee employee = new Employee.Builder(1)
                .setFirstName("Tom")
                .setLastName("Brady")
                .build();

        System.out.println("Employee Id: " + employee.getId());
        System.out.println("Employee Name: " + employee.getFirstName() + " " + employee.getLastName());

        Employee employee2 = new Employee.Builder(2)
                .setFirstName("Peyton")
                .setLastName("Manning")
                .setBirthDate("01-01-1976")
                .setTitle("Quarterback")
                .build();

        System.out.println("Employee Id: " + employee2.getId());
        System.out.println("Employee Name: " + employee2.getFirstName() + " " + employee2.getLastName());
        System.out.println("Employee Birthdate: " + employee2.getBirthdate());
        System.out.println("Employee Title: " + employee2.getTitle());

    }
}


Try creating your own objects to get a better understanding. When you want to add a new property, salary for example, you would have to add it to the Employee class, the constructor, Builder class, and your getter/setter.

public class Employee {

    private final int id;
    private final String firstName;
    private final String lastName;
    private final String title;
    private final String birthdate;
    //new property
    private final int salary;

    private Employee(Builder builder) {
        this.id = builder.id;
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.title = builder.title;
        this.birthdate = builder.birthDate;
        //new property
        this.salary = builder.salary;
    }

    public int getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getTitle() {
        return title;
    }

    public String getBirthdate() {
        return birthdate;
    }

    //new getter for salary
    public int getSalary() {
        return salary;
    }

    public static class Builder {
        private final int id;
        private String firstName;
        private String lastName;
        private String title;
        private String birthDate;
        //salary property
        private int salary;

        public Builder(int id) {
            this.id = id;
        }

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setBirthDate(String birthDate) {
            this.birthDate = birthDate;
            return this;
        }

        //new setter for salary
        public Builder setSalary(int salary) {
            this.salary = salary;
            return this;
        }

        public Employee build() {
            return new Employee(this);
        }
    }
}