TailTemplate Build stunning websites faster with our pre-designed Tailwind CSS templates

Understanding Design Patterns - Simple Factory

This series has been written for developers new to software design patterns and those who find software design patterns difficult to understand.

Dragon Inc. is one of the top toy manufacturers in China. In fact, they're a pioneer in toy manufacturing. They started production at a time when few toys were being produced commercially. Hence, they dominated the market and became the leader in the toy production industry.

Their produceToy() function looked like below:

class ToysFactory
{
        public function produceToy($toyName)
        {
            $toy = null;
            if ('car'==$toyName) {
                $toy = new Car();
            } else if ('helicopter'==$toyName) {
                $toy = new Helicopter();
            }
            $toy->prepare();
            $toy->package();
            $toy->label();
            return $toy;
        }
 
}

Initially they only manufactured toys "Car" and "Helicopter". For this simple task the function worked well and everyone was happy. But not long after that, a cool new toy, the "Jumping Frog" was introduced by the design team. Jumping Frog looked cool and they knew it was going to sell really well, it was time to change the productToy() function:

class ToysFactory
{
 
    public function produceToy($toyName)
    {
            $toy = null;
            if ('car'==$toyName) {
                $toy = new Car();
            } else if ('helicopter'==$toyName) {
                $toy = new Helicopter();
            } else if ('jumpingFrog'==$toyName) {
                $toy = new JumpingFrog();
            }
            $toy->prepare();
            $toy->package();
            $toy->label();
            return $toy;
    }
 
}

As the business grew, more and more toys came into production and the CEO was very happy with the business's financial growth. However, in the development team's office the nightmare was just beginning. The developers were tasked to modify the produceToy() function with the introduction of every new toy. It has violated the open/close principle. Which states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". Every new toy brought in modifications of the produceToy() function.

It was time for refactoring. Let's us take a look at the situation here. What was the real issue with produceToy() function? Concrete classes were instantiated inside ToysFactory and messed up the produceToy() function. The ToysFactory class was tied to the concrete classes of toys. That's the issue.

First, let us create a class to encapsulate the concrete class instantiation.

{
 
    public function createToy($toyName)
    {
        $toy = null;
        if ('car'==$toyName) {
            $toy = new Car();
        } else if ('helicopter'==$toyName) {
            $toy = new Helicopter();
        }
        return $toy;
    }
 
}

Second, we'll use SimpleFactory with our brand new class longer need to touch to create the desired toys:

class ToysFactory
{
 
    public $simpleFactory;
 
    public function __construct(SimpleFactory $simpleFactory)
    {
        $this->simpleFactory = $simpleFactory;
    }
 
    public function produceToy($toyName)
    {
        $toy = null;
        $toy = $this->simpleFactory->createToy($toyName);
        $toy->prepare();
        $toy->package();
        $toy->label();
        return $toy;
    }
 
}

With our brand new class SimpleFactory, things just became cleaner. The Developers no longer need to touch SimpleFactory when a new toy was introduced, and they'll use SimpleFactory` to produce a new toy instead of using the former messy code.

Tha is the Simple Factory. It is not a real design pattern per se, but it's a useful technique that you can apply to your own needs. With Simple Factory, concrete class instantiation is encapsulated. It decouples the client code from the object creation code.

The end

Hopefully this simple tutorial helped you with your development. If you like our post, please follow us on Twitter and help spread the word. We need your support to continue. If you have questions or find our mistakes in above tutorial, do leave a comment below to let us know.