DEV Community

Sarfraz Ahmed
Sarfraz Ahmed

Posted on • Originally published at codeinphp.github.io on

1 1

Factory Design Pattern

Overview

Factory design pattern works like a factory in the real world in that it creates something for others to use. In the context of OOP, it helps in creating and instantiating objects.

Example

Let's say for our application we are using different types of databases based on requirement such as MySQL, PostgreSQL, and SQLite. Our classes look like this:

MySQL:

class MySQLDB
{
    public function setHost($host)
    {
        // code
    }
    public function setDB($db)
    {
        // code
    }
    public function setUserName($user)
    {
        // code
    }
    public function setPassword($pwd)
    {
        // code
    }
    public function connect()
    {
        // code
    }
}
Enter fullscreen mode Exit fullscreen mode

PostgreSQL:

class PostgreSQLDB
{
    public function setHost($host)
    {
        // code
    }
    public function setDB($db)
    {
        // code
    }
    public function setUserName($user)
    {
        // code
    }
    public function setPassword($pwd)
    {
        // code
    }
    public function connect()
    {
        // code
    }
}
Enter fullscreen mode Exit fullscreen mode

...and so on for SQLite database.

Then we instantiate different objects based on configuration:

if (Config::item('db_type') === 'mysql') {
    $DB = new MySQLDB();
    $DB->setHost("host");
    $DB->setDB("db");
    $DB->setUserName("user");
    $DB->setPassword("pwd");
    $DB->connect();
}
elseif (Config::item('db_type') === 'postgre') {
    $DB = new PostgreSQLDB();
    $DB->setHost("host");
    $DB->setDB("db");
    $DB->setUserName("user");
    $DB->setPassword("pwd");
    $DB->connect();
}
elseif (Config::item('db_type') === 'sqlite') {
    $DB = new SQLiteDB();
    $DB->setHost("host");
    $DB->setDB("db");
    $DB->setUserName("user");
    $DB->setPassword("pwd");
    $DB->connect();
}
Enter fullscreen mode Exit fullscreen mode

Generally above works but it creates problems in rather big applications. Above code has these problems:

  • Should you add more database types, code would keep on growing making it complex
  • The code is hard coded with database type names
  • Whole process becomes tedious

To solve these issues, we can instead create a central factory object that would create those objects for us:

class DBFactory
{
    protected $driver = null;

    public function setDriver($driver)
    {
        $this->driver = $driver;
    }

    public function makeDB($host, $user, $pass, $dbname)
    {
        if ($this->driver === 'mysql') {
            $DB = new MySQLDB();
        }
        elseif ($this->driver === 'postgre') {
            $DB = new PostgreSQLDB();
        }
        elseif ($this->driver === 'sqlite') {
            $DB = new SQLiteDB();
        }

        $DB->setHost($host);
        $DB->setDB($dbname);
        $DB->setUserName($user);
        $DB->setPassword($pass);
        $DB->connect();

        return $DB;
    }
}
Enter fullscreen mode Exit fullscreen mode

And then using it:

$dbFactory = new DBFactory;
$dbFactory->setDriver(Config::item('db_type'));
$DB = $dbFactory->makeDB("host", "db", "user", "pwd");
Enter fullscreen mode Exit fullscreen mode

And that's it. You won't have to modify above code, it will always remain same, we have moved the complex object creation logic separate in the factory itself which now makes our code a lot more easier to work with.

Please notice that there are some variations of factory design pattern such as simple factory, abstract factory and factory method. In this example, we used the factory method eg we used a method named makeDB() to create our objects. Other variations are almost similar; for example with abstract factory, you actually create an abstract class and then all concrete classes should extend it. It just enforces commonality between similar concrete classes.

Note: In modern day, the object creation has become very simple with the help of Dependency Injection Containers and Service Locators. There are quite some DICs to choose from for PHP.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay