The Factory Method Pattern
Published: 2022-01-24 12:09:17

>**Defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method let a class defer instantiation to subclasses.**

When talking about factory method, we talk about a pattern that solves a common problem in software development (that’s why it’s a design pattern). That problem it’s called **class dependency**.

Of course it solves other problems and in this article I’m going to mention some of them.

So, according to the definition, we need to define an interface (remember that when we talk about interface is not necessary an “interface” type, it could be an abstract class or any super class). But what does the interface need to have? What methods we have to define? Also, does it need properties?

Well, the answer is simple, we need the **Factory Method**. Be careful that when we say that the interface needs the factory method it doesn’t mean that is the only method the interface can have. The **Factory Method** is the method that have all the logic to create an object.

## Creating the class diagram

Let’s begin by creating the part where it say “_Defines an interface for creating an object, but lets subclasses decid which class to instantiate._”



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdwg37pysruia5neipis.png)

Pretty simple, right?

Now we have to complete the second part of the diagram. For this, we need to think that the subclass is in charge of creating the objects, and because this class decides which object is going to create, the only way to return the same type of an object is by creating another interface for this object.

What I mean with this is that if we have a **ConcreteFactoryClass** this class can instantiate different concrete classes. For example we can have a **DatabaseFactory**, and this factory can return an instance of MySQL, MongoDB, PostgreSQL, etc. This is not right because this factory needs to return a type that is common for every Database classes, and that is why every concrete database needs to implement an interface.

So, with this definition, the **Factory Method Pattern** class diagram looks like this.


![Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28ybkz6arz791vxphf7t.jpeg)

## Applying The Factory Method Pattern

Let’s imagine that we need to create multiple database classes like MySQL, PostgreSQL and MongoDB. They are simple classes that have some methods like “select”, “insert”, “update” and “delete”.

Each class know the syntax to execute each statement.

Our class diagram looks like this.


![Concrete Factory Method Pattern](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n3su97vxto7qk4h90o7.jpeg)

Notice that the **create** method in the factory is our **FactoryMethod**.

## Questions you may ask

### Why do we need a FactoryInterface if there is only one ConcreteFactory?

Each case is different, we provide an interface because we need to make sure that the ConcreteFactory have this method. In some cases is possible you could have many ConcreteFactories (maybe a company and its branch offices).

### Why this pattern solve class dependencies?

Imagine if we have in the main class (where we use the factory) a lot of if statements asking if the type is “mysql” or “postgresql”, etc. For each specific case it instantiate the concrete class. Thus, the main class will depend on every concrete DB class. Applying the factory method, the main class will depend on the **DB** abstract class.

### Can this pattern solve an Open-Close principle violation?

Of course, let's the take the example of the previous question (the one where we have many if statements). So every time we need to add a new concrete DB class we have to change the code of our main class. By applying the **factory method**, any new concrete class will be added in our factory not in the main class.

##Code implementation

[Factory Method Pattern](https://github.com/bakle/Design-Patterns/tree/main/src/FactoryMethodPattern)


**Follow me on:** [Twitter](https://twitter.com/Bashir_Akle)