Introduction
Creational design patterns focus on object creation mechanisms, trying to create objects in a manner suitable to the situation. These patterns provide various object creation methods that increase flexibility and reuse of existing code.
Builder Pattern
The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations.
class Computer:
def __init__(self):
self.cpu = None
self.ram = None
self.storage = None
def __str__(self):
return f"CPU: {self.cpu}, RAM: {self.ram}, Storage: {self.storage}"
class ComputerBuilder:
def __init__(self):
self.computer = Computer()
def set_cpu(self, cpu):
self.computer.cpu = cpu
return self
def set_ram(self, ram):
self.computer.ram = ram
return self
def set_storage(self, storage):
self.computer.storage = storage
return self
def build(self):
return self.computer
builder = ComputerBuilder()
computer = builder.set_cpu("Intel i7").set_ram("16GB").set_storage("512GB SSD").build()
print(computer) # CPU: Intel i7, RAM: 16GB, Storage: 512GB SSD
Prototype Pattern
The Prototype pattern creates new objects by copying an existing object, known as the prototype.
import copy
class Prototype:
def __init__(self):
self.data = {}
def clone(self):
return copy.deepcopy(self)
class ConcretePrototype(Prototype):
def __init__(self, value):
super().__init__()
self.data["value"] = value
prototype = ConcretePrototype("original")
clone = prototype.clone()
clone.data["value"] = "modified"
print(prototype.data["value"]) # original
print(clone.data["value"]) # modified
Abstract Factory Pattern
The Abstract Factory pattern provides an interface for creating families of related objects without specifying their concrete classes.
class Button:
def render(self):
pass
class TextBox:
def render(self):
pass
class WindowsButton(Button):
def render(self):
return "Windows Button"
class MacButton(Button):
def render(self):
return "Mac Button"
class WindowsTextBox(TextBox):
def render(self):
return "Windows TextBox"
class MacTextBox(TextBox):
def render(self):
return "Mac TextBox"
class UIFactory:
def create_button(self):
pass
def create_textbox(self):
pass
class WindowsFactory(UIFactory):
def create_button(self):
return WindowsButton()
def create_textbox(self):
return WindowsTextBox()
class MacFactory(UIFactory):
def create_button(self):
return MacButton()
def create_textbox(self):
return MacTextBox()
def create_ui(factory):
button = factory.create_button()
textbox = factory.create_textbox()
print(button.render())
print(textbox.render())
create_ui(WindowsFactory())
Practice Problems
- Build a Pizza builder with different toppings, sizes, and crust types.
- Implement a document prototype system with different document types.
- Create an abstract factory for different UI themes (Light/Dark) with buttons, inputs, and cards.
- Build a car builder with different configurations for engine, color, and features.
- Implement a nested object copy using the prototype pattern.