Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the spectra-pro domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home4/mahidhar/public_html/wp-includes/functions.php on line 6114
Java Creational Patterns | tutorialQ

Java Creational Patterns

Design Patterns in Java: Creational Patterns

Design patterns are general reusable solutions to common problems in software design. Creational patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. In this discussion, we’ll cover four creational patterns: Singleton, Factory, Builder, and Facade.

1. Singleton Pattern

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.

Implementation

  • Eager Initialization:
Java
  public class EagerSingleton {
      private static final EagerSingleton INSTANCE = new EagerSingleton();

      private EagerSingleton() {}

      public static EagerSingleton getInstance() {
          return INSTANCE;
      }
  }
  • Lazy Initialization:
Java
  public class LazySingleton {
      private static LazySingleton instance;

      private LazySingleton() {}

      public static LazySingleton getInstance() {
          if (instance == null) {
              instance = new LazySingleton();
          }
          return instance;
      }
  }
  • Thread-Safe Singleton:
Java
  public class ThreadSafeSingleton {
      private static ThreadSafeSingleton instance;

      private ThreadSafeSingleton() {}

      public static synchronized ThreadSafeSingleton getInstance() {
          if (instance == null) {
              instance = new ThreadSafeSingleton();
          }
          return instance;
      }
  }
  • Double-Checked Locking:
Java
  public class DoubleCheckedLockingSingleton {
      private static volatile DoubleCheckedLockingSingleton instance;

      private DoubleCheckedLockingSingleton() {}

      public static DoubleCheckedLockingSingleton getInstance() {
          if (instance == null) {
              synchronized (DoubleCheckedLockingSingleton.class) {
                  if (instance == null) {
                      instance = new DoubleCheckedLockingSingleton();
                  }
              }
          }
          return instance;
      }
  }

2. Factory Pattern

The Factory pattern provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

Implementation

    Java
      // Product interface
      public interface Shape {
          void draw();
      }
    
      // Concrete Products
      public class Circle implements Shape {
          public void draw() {
              System.out.println("Drawing Circle");
          }
      }
    
      public class Rectangle implements Shape {
          public void draw() {
              System.out.println("Drawing Rectangle");
          }
      }
    
      // Factory Class
      public class ShapeFactory {
          public Shape getShape(String shapeType) {
              if (shapeType == null) {
                  return null;
              }
              if (shapeType.equalsIgnoreCase("CIRCLE")) {
                  return new Circle();
              } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
                  return new Rectangle();
              }
              return null;
          }
      }
    
      // Client
      public class FactoryPatternDemo {
          public static void main(String[] args) {
              ShapeFactory shapeFactory = new ShapeFactory();
    
              // Get an object of Circle and call its draw method.
              Shape shape1 = shapeFactory.getShape("CIRCLE");
              shape1.draw();
    
              // Get an object of Rectangle and call its draw method.
              Shape shape2 = shapeFactory.getShape("RECTANGLE");
              shape2.draw();
          }
      }

    3. Builder Pattern

    The Builder pattern is used to create complex objects step by step. It allows you to construct objects piece by piece.

    Implementation

    • Example:
    Java
      // Product class
      public class House {
          private String foundation;
          private String structure;
          private String roof;
          private String interior;
    
          // Private constructor to enforce the use of the builder
          private House(HouseBuilder builder) {
              this.foundation = builder.foundation;
              this.structure = builder.structure;
              this.roof = builder.roof;
              this.interior = builder.interior;
          }
    
          @Override
          public String toString() {
              return "House{" +
                     "foundation='" + foundation + '\'' +
                     ", structure='" + structure + '\'' +
                     ", roof='" + roof + '\'' +
                     ", interior='" + interior + '\'' +
                     '}';
          }
    
          // Static inner Builder class
          public static class HouseBuilder {
              private String foundation;
              private String structure;
              private String roof;
              private String interior;
    
              public HouseBuilder setFoundation(String foundation) {
                  this.foundation = foundation;
                  return this;
              }
    
              public HouseBuilder setStructure(String structure) {
                  this.structure = structure;
                  return this;
              }
    
              public HouseBuilder setRoof(String roof) {
                  this.roof = roof;
                  return this;
              }
    
              public HouseBuilder setInterior(String interior) {
                  this.interior = interior;
                  return this;
              }
    
              public House build() {
                  return new House(this);
              }
          }
      }
    
      // Client
      public class BuilderPatternDemo {
          public static void main(String[] args) {
              House house = new House.HouseBuilder()
                      .setFoundation("Concrete foundation")
                      .setStructure("Wooden structure")
                      .setRoof("Tile roof")
                      .setInterior("Modern interior")
                      .build();
    
              System.out.println(house);
          }
      }

    4. Facade Pattern

    The Facade pattern provides a simplified interface to a complex subsystem. It hides the complexities of the system and provides an easy-to-use interface.

    Implementation

    • Example:
    Java
      // Subsystem classes
      public class CPU {
          public void start() {
              System.out.println("CPU started");
          }
    
          public void stop() {
              System.out.println("CPU stopped");
          }
      }
    
      public class Memory {
          public void load(long position, byte[] data) {
              System.out.println("Memory loaded at position " + position);
          }
    
          public void free(long position) {
              System.out.println("Memory freed at position " + position);
          }
      }
    
      public class HardDrive {
          public byte[] read(long lba, int size) {
              System.out.println("Hard drive read at lba " + lba + " with size " + size);
              return new byte[size];
          }
      }
    
      // Facade class
      public class ComputerFacade {
          private CPU cpu;
          private Memory memory;
          private HardDrive hardDrive;
    
          public ComputerFacade() {
              this.cpu = new CPU();
              this.memory = new Memory();
              this.hardDrive = new HardDrive();
          }
    
          public void start() {
              cpu.start();
              memory.load(0, hardDrive.read(0, 4096));
              System.out.println("Computer started");
          }
    
          public void stop() {
              memory.free(0);
              cpu.stop();
              System.out.println("Computer stopped");
          }
      }
    
      // Client
      public class FacadePatternDemo {
          public static void main(String[] args) {
              ComputerFacade computer = new ComputerFacade();
              computer.start();
              computer.stop();
          }
      }

    Summary

    Creational design patterns provide solutions to instantiate objects in different ways to simplify system designs and make them more flexible and reusable.

    1. Singleton Pattern: Ensures a class has only one instance and provides a global point of access to it.
    2. Factory Pattern: Provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.
    3. Builder Pattern: Constructs complex objects step by step. The final step returns the object.
    4. Facade Pattern: Provides a simplified interface to a complex subsystem.

    Understanding and implementing these patterns can significantly improve the design and maintainability of your code.

    Scroll to Top