IT creational patterns

From A Technological Wiki
Revision as of 22:01, 20 October 2025 by Root (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Creational patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.

When to use them

  • When the creation process is complex: If creating an object is a multi-step process or requires logic, it's best encapsulated.
  • When you need to decouple the system from specific classes: This helps in making the system more modular and flexible.
  • When you want to abstract the instantiation process: Hide the logic of creating objects and just present a ready-to-use object.

Fundamental creational patterns

Singleton

Ensure a class has only one instance and provide a global point to access it.

class Singleton {
    private static $instance = null;
    private function __construct() {}

    public static function getInstance() {
        if (self::$instance == null) {
            self::$instance = new Singleton();
        }
        return self::$instance;
    }
}
$instance = Singleton::getInstance();

Factory Method

A method for creating an object in a super class but allows subclasses to alter the type of objects that will be created.

interface Product {
    public function create();
}

class ConcreteProductA implements Product {
    public function create() {
        return "Product A";
    }
}

class ConcreteProductB implements Product {
    public function create() {
        return "Product B";
    }
}

abstract class Creator {
    abstract public function factoryMethod(): Product;
}

class ConcreteCreatorA extends Creator {
    public function factoryMethod(): Product {
        return new ConcreteProductA();
    }
}

class ConcreteCreatorB extends Creator {
    public function factoryMethod(): Product {
        return new ConcreteProductB();
    }
}

$creator = new ConcreteCreatorA();
$product = $creator->factoryMethod();
echo $product->create();  // Outputs "Product A"

Abstract Factory

Creates an object from several families of classes without specifying the exact class name.

interface Button {
    public function paint();
}

class WinButton implements Button {
    public function paint() {
        return "Windows Button";
    }
}

class MacButton implements Button {
    public function paint() {
        return "Mac Button";
    }
}

interface GUIFactory {
    public function createButton(): Button;
}

class WinFactory implements GUIFactory {
    public function createButton(): Button {
        return new WinButton();
    }
}

class MacFactory implements GUIFactory {
    public function createButton(): Button {
        return new MacButton();
    }
}

$guiFactory = new MacFactory();
$button = $guiFactory->createButton();
echo $button->paint();  // Outputs "Mac Button"

Prototype

Creates objects by cloning an existing object, known as the prototype.

abstract class Prototype {
    abstract public function __clone();
}

class ConcretePrototype extends Prototype {
    public $property;
    public function __clone() {}
}

$prototype = new ConcretePrototype();
$prototype->property = "Original";
$clone = clone $prototype;
$clone->property = "Cloned";
echo $prototype->property;  // Outputs "Original"
echo $clone->property;      // Outputs "Cloned"

Builder

Allows constructing complex objects step by step. Separates the construction of a complex object from its representation.

class Product {
    private $parts = [];

    public function add($part) {
        $this->parts[] = $part;
    }

    public function show() {
        return implode(", ", $this->parts);
    }
}

class Builder {
    private $product;

    public function __construct() {
        $this->product = new Product();
    }

    public function buildPartA() {
        $this->product->add('PartA');
    }

    public function buildPartB() {
        $this->product->add('PartB');
    }

    public function getResult() {
        return $this->product;
    }
}

$builder = new Builder();
$builder->buildPartA();
$builder->buildPartB();
$product = $builder->getResult();
echo $product->show();  // Outputs "PartA, PartB"