Design patterns are guidelines for solving repetitive problems.

Quote from Wikipedia:
Software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design.
Types of Design Patterns
- Generating Objects
- Patterns for Flexible Object Programming
- Performing and Representing Tasks
- Enterprise Patterns
- Database Patterns
The Singleton Pattern
The singleton pattern is a software design pattern that restricts the instantiation of a class to one object.

Purpose
A special class that generates one—and only one—object instance.
Example
Imagine a Settings class that holds application-level information.
- A Settings object should be available to any object in your system.
- A Settings object should not be stored in a global variable, which can be overwritten.
- There should be no more than one Preferences object in play in the system.
Implementation
class Settings
{
private $props = [];
private static $instance;
private function __construct()
{
}
public static function getInstance()
{
if (empty(self::$instance)) {
self::$instance = new Preferences();
}
return self::$instance;
}
public function setProperty(string $key, string $val)
{
$this->props[$key] = $val;
}
public function getProperty(string $key): string
{
return $this->props[$key];
}
}
Factory Method Pattern
Factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.

Purpose
Building an inheritance hierarchy of creator classes.
Example
You need to create a variety of products of certain kinds.
Implementation
abstract class Product
{
abstract public function getName(): string;
abstract public function getSize(): int;
}
class ConcreteProduct extends Product
{
protected $name;
protected $size;
public function __construct(string $name, int $size)
{
$this->name = $name;
$this->size = $size;
}
public function getName(): string
{
return $this->name;
}
public function getSize(): int
{
return $this->size;
}
}
abstract class ProductManager
{
abstract public function getProduct($name, $size): Product;
}
class ConcreteProductManager extends ProductManager
{
public function getProduct($name, $size): Product
{
return new ConcreteProduct($name, $size);
}
}
Abstract Factory Pattern
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.

Purpose
Grouping the creation of functionally related products
Example
You need to create a family of products of different types.
Implementation
class ProductA1 extends ProductA{...}
class ProductB1 extends ProductB{...}
class ProductA2 extends ProductA{...}
class ProductB2 extends ProductB{...}
abstract class ProductManager
{
abstract function createProductA();
abstract function createProductB();
}
class Product1Manager extends ProductManager
{
public function createProductA() {
return new ProductA1();
}
public function createProductB() {
return new ProductB1();
}
}
class Product2Manager extends ProductManager
{
public function createProductA() {
return new ProductA2();
}
public function createProductB() {
return new ProductB2();
}
}
Prototype
Prototype pattern is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.

Purpose
Using clone to generate objects.
Example
You need to create an object that is similar to an existing object.
Implementation
class Product
{
protected $name;
protected $size;
public function __construct(string $name, int $size)
{
$this->name = $name;
$this->size = $size;
}
public function getName(): string
{
return $this->name;
}
public function getSize(): int
{
return $this->size;
}
}
$product = new Product('Nike', 56);
echo $product->getName(); // Nike
echo $product->getSize(); //56
// Clone and modify what is required
$cloned = clone $product;
$cloned->setName('Adidas');
echo $cloned->getName(); // Adidas
echo $cloned->getSize(); // 56
Service Locator
The service locator pattern is a design pattern used in software development to encapsulate the processes involved in obtaining a service with a strong abstraction layer.

Purpose
Asking your system for objects. To implement a loosely coupled architecture in order to get better testable, maintainable and extendable code.
Implementation
class Settings
{
static $DbType = 'PostgreSql';
}
class Foo
{
protected $db;
public function __construct()
{
$this->db = Settings::$DbType;
}
}
Dependency Injection
Dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object.

Purpose
Letting your system give you objects. To implement a loosely coupled architecture in order to get better testable, maintainable and extendable code.
Implementation
class Computer
{
protected $hardDrive;
public function __construct($hardDrive)
{
$this->hardDrive = $hardDrive();
}
}
$hardDrive = new HardDrive();
$computer = new Computer($hardDrive);
Summary
This post covered some of the tricks that you can use to generate objects.
Marat Badykov
Full-stack web developer. I enjoy writing Php, Java, and Js.