SkillAgentSearch skills...

Design Patterns For Humans

An ultra-simplified explanation to design patterns

Install / Use

npx skills add nilbuild/design-patterns-for-humans

Installs into whichever agent you are using.

About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

<br> <p align="center"> <img src="./.github/banner.svg" height="150px" /> </p>
<p align="center"> 🎉 Ultra-simplified explanation to design patterns! 🎉 </p> <p align="center"> A topic that can easily make anyone's mind wobble. Here I try to make them stick in to your<br> mind (and maybe mine) by explaining them in the <i>simplest</i> way possible. </p>

<sub>Check out my other project and say "hi" on Twitter.</sub>

<br>

|Creational Design Patterns|Structural Design Patterns|Behavioral Design Patterns| |:-|:-|:-| |Simple Factory|Adapter|Chain of Responsibility| |Factory Method|Bridge|Command| |Abstract Factory|Composite|Iterator| |Builder|Decorator|Mediator| |Prototype|Facade|Memento| |Singleton|Flyweight|Observer| ||Proxy|Visitor| |||Strategy| |||State| |||Template Method|

<br>

Introduction

Design patterns are solutions to recurring problems; guidelines on how to tackle certain problems. They are not classes, packages or libraries that you can plug into your application and wait for the magic to happen. These are, rather, guidelines on how to tackle certain problems in certain situations.

Design patterns are solutions to recurring problems; guidelines on how to tackle certain problems

Wikipedia describes them as

In software engineering, a software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations.

⚠️ Be Careful

  • Design patterns are not a silver bullet to all your problems.
  • Do not try to force them; bad things are supposed to happen, if done so.
  • Keep in mind that design patterns are solutions to problems, not solutions finding problems; so don't overthink.
  • If used in a correct place in a correct manner, they can prove to be a savior; or else they can result in a horrible mess of a code.

Also note that the code samples below are in PHP-7, however this shouldn't stop you because the concepts are same anyways.

Types of Design Patterns

Creational Design Patterns

In plain words

Creational patterns are focused towards how to instantiate an object or group of related objects.

Wikipedia says

In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.

🏠 Simple Factory

Real world example

Consider, you are building a house and you need doors. You can either put on your carpenter clothes, bring some wood, glue, nails and all the tools required to build the door and start building it in your house or you can simply call the factory and get the built door delivered to you so that you don't need to learn anything about the door making or to deal with the mess that comes with making it.

In plain words

Simple factory simply generates an instance for client without exposing any instantiation logic to the client

Wikipedia says

In object-oriented programming (OOP), a factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be "new".

Programmatic Example

First of all we have a door interface and the implementation

interface Door
{
    public function getWidth(): float;
    public function getHeight(): float;
}

class WoodenDoor implements Door
{
    protected $width;
    protected $height;

    public function __construct(float $width, float $height)
    {
        $this->width = $width;
        $this->height = $height;
    }

    public function getWidth(): float
    {
        return $this->width;
    }

    public function getHeight(): float
    {
        return $this->height;
    }
}

Then we have our door factory that makes the door and returns it

class DoorFactory
{
    public static function makeDoor($width, $height): Door
    {
        return new WoodenDoor($width, $height);
    }
}

And then it can be used as

// Make me a door of 100x200
$door = DoorFactory::makeDoor(100, 200);

echo 'Width: ' . $door->getWidth();
echo 'Height: ' . $door->getHeight();

// Make me a door of 50x100
$door2 = DoorFactory::makeDoor(50, 100);

When to Use?

When creating an object is not just a few assignments and involves some logic, it makes sense to put it in a dedicated factory instead of repeating the same code everywhere.

🏭 Factory Method

Real world example

Consider the case of a hiring manager. It is impossible for one person to interview for each of the positions. Based on the job opening, she has to decide and delegate the interview steps to different people.

In plain words

It provides a way to delegate the instantiation logic to child classes.

Wikipedia says

In class-based programming, the 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. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.

Programmatic Example

Taking our hiring manager example above. First of all we have an interviewer interface and some implementations for it

interface Interviewer
{
    public function askQuestions();
}

class Developer implements Interviewer
{
    public function askQuestions()
    {
        echo 'Asking about design patterns!';
    }
}

class CommunityExecutive implements Interviewer
{
    public function askQuestions()
    {
        echo 'Asking about community building';
    }
}

Now let us create our HiringManager

abstract class HiringManager
{

    // Factory method
    abstract protected function makeInterviewer(): Interviewer;

    public function takeInterview()
    {
        $interviewer = $this->makeInterviewer();
        $interviewer->askQuestions();
    }
}

Now any child can extend it and provide the required interviewer

class DevelopmentManager extends HiringManager
{
    protected function makeInterviewer(): Interviewer
    {
        return new Developer();
    }
}

class MarketingManager extends HiringManager
{
    protected function makeInterviewer(): Interviewer
    {
        return new CommunityExecutive();
    }
}

and then it can be used as

$devManager = new DevelopmentManager();
$devManager->takeInterview(); // Output: Asking about design patterns

$marketingManager = new MarketingManager();
$marketingManager->takeInterview(); // Output: Asking about community building.

When to use?

Useful when there is some generic processing in a class but the required sub-class is dynamically decided at runtime. Or putting it in other words, when the client doesn't know what exact sub-class it might need.

🔨 Abstract Factory

Real world example

Extending our door example from Simple Factory. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc.

In plain words

A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.

Wikipedia says

The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes

Programmatic Example

Translating the door example above. First of all we have our Door interface and some implementation for it

interface Door
{
    public function getDescription();
}

class WoodenDoor implements Door
{
    public function getDescription()
    {
        echo 'I am a wooden door';
    }
}

class IronDoor implements Door
{
    public function getDescription()
    {
        echo 'I am an iron door';
    }
}

Then we have some fitting experts for each door type

interface DoorFittingExpert
{
    public function getDescription();
}

class Welder implements DoorFittingExpert
{
    public function getDescription()
    {
        echo 'I can only fit iron doors';
    }
}

class Carpenter implements DoorFittingExpert
{
    public function getDescription()
    {
        echo 'I can only fit wooden doors';
    }
}

Now we have our abstract factory

Related Skills

View on GitHub
GitHub Stars48.4k
CategoryDesign
Updated3h ago
Forks5.6k

Security Score

85/100

Audited on Aug 8, 2026

No findings