Mr.Raindrop

Mr.Raindrop

一切都在无可挽回的走向庸俗。
twitter
github

Introduction to Design Patterns - Creational Patterns

Creational Patterns#

Creational patterns: These are patterns for creating objects, abstracting the process of instantiation. They focus on the creation of objects, encapsulating the process of object creation, allowing client programs to use objects without concerning themselves with the logic of the creation process.

Simple Factory Pattern#

Simple Factory Pattern: Also known as Static Factory Method pattern, in the Simple Factory Pattern, you can return instances of different classes based on different parameters (for example, a button returns different shapes based on the shape parameter). The Simple Factory Pattern specifically defines a class responsible for creating instances of other classes, which usually share a common parent class.

image

Implementation Method#

  • Factory Class: Responsible for creating corresponding product objects based on input parameters (such as strings, enums, etc.).

    public class VendorFactory {
        public static IVender createVendor(String type) {
            switch (type) {
                case "A": return new VendorA();
                case "B": return new VendorB();
                default: throw new RuntimeException("Supplier does not exist");
            }
        }
    }
    
  • Abstract Product: Defines the common interface for all products.

    public interface IVender {
        void order();
    }
    
  • Concrete Product: Classes that implement the abstract product interface, with each class corresponding to a type of product.

    public class VendorA implements IVender {
        @Override
        public void order() { System.out.println("Order placed successfully by Supplier A"); }
    }
    

Usage#

IVender vendor = VendorFactory.createVendor("A");
vendor.order();  // Output: Order placed successfully by Supplier A

Factory Method Pattern#

The core idea is to abstract the object creation process, allowing subclasses to decide which specific class to instantiate, thereby extending system functionality without modifying client code.

Components#

  • Abstract Factory (Creator)
  • Concrete Factory (Concrete Creator)
  • Abstract Product (Product)
  • Concrete Product (Concrete Product)

Implementation#

// Abstract Product
interface Car {
    void show();
}

// Concrete Product
class CarA implements Car {
    @Override
    public void show() { System.out.println("Xiaomi SU7"); }
}

// Abstract Factory
abstract class Factory {
    public abstract Car createCar();
}

// Concrete Factory
class CarFactoryA extends Factory {
    @Override
    public Car createCar() { return new CarA(); }
}

../_images/SimpleFactory.jpg

Implementation Method#

  • Factory Class: Responsible for creating corresponding product objects based on input parameters (such as strings, enums, etc.).

    public class VendorFactory {
        public static IVender createVendor(String type) {
            switch (type) {
                case "A": return new VendorA();
                case "B": return new VendorB();
                default: throw new RuntimeException("Supplier does not exist");
            }
        }
    }
    
  • Abstract Product: Defines the common interface for all products.

    public interface IVender {
        void order();
    }
    
  • Concrete Product: Classes that implement the abstract product interface, with each class corresponding to a type of product.

    public class VendorA implements IVender {
        @Override
        public void order() { System.out.println("Order placed successfully by Supplier A"); }
    }
    

Usage#

IVender vendor = VendorFactory.createVendor("A");
vendor.order();  // Output: Order placed successfully by Supplier A

Abstract Factory Pattern#

Generally, a concrete factory has only one factory method or a set of overloaded factory methods. However, sometimes we need a factory that can provide multiple product objects, rather than a single product object.

Application Conditions

The Abstract Factory Pattern is needed when the specific products that the factory needs to produce are not simple objects, but multiple specific products belonging to different types in different product hierarchy structures.

The Factory Method Pattern targets a single product hierarchy, while the Abstract Factory Pattern must deal with multiple product hierarchies. A factory hierarchy can be responsible for creating product objects from multiple different product hierarchies. When a factory hierarchy can create all objects in a product family that belongs to different product hierarchies, the Abstract Factory Pattern is simpler and more efficient than the Factory Method Pattern.

Pattern Structure#

  • AbstractFactory: Abstract Factory
  • ConcreteFactory: Concrete Factory
  • AbstractProduct: Abstract Product
  • Product: Concrete Product

image

[Example](Abstract Factory Pattern (Easy to Understand) - CSDN Blog)

image

Prototype Pattern#

Creates new objects by copying existing objects (prototypes) rather than instantiating them through traditional constructors. It is particularly suitable for scenarios that require efficient creation of complex objects or dynamically generating similar objects.

Components#

  • Abstract Prototype: Defines the interface for the clone method (e.g., Cloneable interface).
  • Concrete Prototype: Specific objects that implement the cloning logic (e.g., overriding the clone() method).
  • Client: Creates new objects by calling the clone method of the prototype object.

Cloning Methods: Shallow copy, deep copy (via implementation or serialization).

Implementation#

// Abstract Prototype (implements Cloneable interface)
public abstract class Shape implements Cloneable {
    protected String type;
    public abstract void draw();

    @Override
    public Shape clone() {
        try {
            return (Shape) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();  // Will not happen
        }
    }
}

// Concrete Prototype: Circle
public class Circle extends Shape {
    public Circle() {
        type = "Circle";
    }

    @Override
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

// Client call
Shape original = new Circle();
Shape clone = original.clone();  // Clone object
clone.draw();  // Output: Drawing Circle

Singleton Pattern#

Ensures that a class has only one instance throughout the application lifecycle and provides a global access point. The Singleton Pattern helps avoid resource waste and data inconsistency issues caused by multiple instances.

How to ensure there is only one singleton:

Let the class itself be responsible for maintaining its unique instance. This class can ensure that no other instances are created and can provide a method to access that instance. This is the motivation behind the Singleton Pattern.

image

Implementation Method#

Singleton Pattern - Zhihu

Lazy Initialization (created only when first called)

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // Private constructor
    }

    public static Singleton getInstance() {
        if (instance == null) { // First check
            instance = new Singleton();
        }
        return instance;
    }
}

Eager Initialization (instance created when class is loaded)

public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {
        // Private constructor
    }

    public static Singleton getInstance() {
        return instance;
    }
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.