Creational design patterns

Let’s delve deeper into each of these creational design patterns:

1. **Simple Factory:**
– **Purpose:** This pattern helps in creating instances of different classes based on provided data, without exposing the creation logic.
– **Example:** In a payment processing system, a Simple Factory can handle the creation of different payment methods (credit card, PayPal, etc.) based on user input.

class PaymentProcessor
def self.create_payment_method(type)
case type
when :credit_card
CreditCard.new
when :paypal
PayPal.new
else
raise "Invalid payment method"
end
end
end

class CreditCard
# Credit card specific logic
end

class PayPal
# PayPal specific logic
end

# Usage:
payment_method = PaymentProcessor.create_payment_method(:credit_card)

2. **Factory Method:**
– **Purpose:** It provides an interface for creating instances of a class, but allows subclasses to alter the type of instances that will be created.
– **Example:** In a vehicle manufacturing system, a `VehicleFactory` interface can have subclasses like `CarFactory` and `MotorcycleFactory`, each responsible for creating respective vehicles.

class VehicleFactory
def create_vehicle
raise NotImplementedError, "Subclasses must implement create_vehicle"
end
end

class CarFactory < VehicleFactory
def create_vehicle
Car.new
end
end

class MotorcycleFactory < VehicleFactory
def create_vehicle
Motorcycle.new
end
end

# Usage:
car_factory = CarFactory.new
vehicle = car_factory.create_vehicle

3. **Abstract Factory:**
– **Purpose:** This pattern provides an interface to create families of related or dependent objects without specifying their concrete classes.
– **Example:** In a user interface library, an `AbstractUIFactory` can create different UI elements like buttons, text fields, and checkboxes that are consistent in style.
class AbstractUIFactory
def create_button
raise NotImplementedError, "Subclasses must implement create_button"
end

def create_text_field
raise NotImplementedError, “Subclasses must implement create_text_field”
end
end

class WindowsUIFactory < AbstractUIFactory
def create_button
WindowsButton.new
end

def create_text_field
WindowsTextField.new
end
end

class MacOSUIFactory < AbstractUIFactory
def create_button
MacOSButton.new
end

def create_text_field
MacOSTextField.new
end
end

# Usage:
ui_factory = WindowsUIFactory.new
button = ui_factory.create_button

4. **Singleton:**
– **Purpose:** Ensures a class has only one instance throughout the program’s execution and provides a global point of access to it.
– **Example:** In a logging system, a Singleton ensures that there’s only one logger instance across the application.
class Logger
@@instance = Logger.new

def self.instance
@@instance
end

private_class_method :new

def log(message)
# Log the message
end
end

# Usage:
logger = Logger.instance
logger.log(“This is a log message”)

5. **Builder:**
– **Purpose:** Separates the construction of a complex object from its representation. It allows different representations to be created based on needs.
– **Example:** In a document creation tool, a `DocumentBuilder` can be used to construct documents in various formats (e.g., HTML, PDF) with different structures.
class DocumentBuilder
def initialize(format)
@document = Document.new(format)
end

def add_heading(text)
@document.add_element(Heading.new(text))
end

def add_paragraph(text)
@document.add_element(Paragraph.new(text))
end

def build
@document
end
end

# Usage:
builder = DocumentBuilder.new(:pdf)
builder.add_heading(“Title”)
builder.add_paragraph(“Content”)
document = builder.build

6. **Prototype:**
– **Purpose:** It involves creating new objects by copying an existing object, known as the prototype. This pattern is useful when creating complex objects is more costly.
– **Example:** In a graphic design software, users can duplicate elements (like shapes or symbols) to create variations without starting from scratch.

class Shape
attr_accessor :color

def clone
raise NotImplementedError, “Subclasses must implement clone”
end
end

class Circle < Shape def clone cloned_circle = Circle.new cloned_circle.color = @color cloned_circle end end # Usage: original_circle = Circle.new original_circle.color = “red” cloned_circle = original_circle.clone cloned_circle.color #=> “red”

These creational design patterns collectively offer powerful strategies for object creation. By choosing the appropriate pattern, you can achieve flexibility, maintainability, and scalability in your software design. Each pattern serves a specific purpose, allowing developers to make informed decisions based on the needs and requirements of their applications.

Leave a Reply