Get up to 80 % extra points for free! More info:

Factory (method)

The Factory design pattern is one of the most important design patterns which allows higher abstraction when creating a class instance than a classical constructor. Typically, it's used to encapsulate more complex instance initialization and to create different instance types based on a string.

Motivation

In applications, it sometimes happens that we need to create an instance of a class and initialize it further more. Form components are a good practical example where creating an instance is not just enough, but we also need to set many other properties (dimensions, caption, position, color...). If you create 20 similar buttons somewhere in your application and it takes 10 lines to create each button, you might consider separating the code into a method. Congratulations, you have just invented the factory (of course, the pattern has some more formalities).

The factory can also store variables needed to create the instances. Like this, these variables don't need to be passed through the entire application. Another advantage is the return type which doesn't have to be exactly the type of the instance we're creating. We can return one of the parent classes or even an interface. We'll take a closer look at each of these cases.

The Factory design pattern comes in different forms and there are also its other variations (Factory, Abstract Factory, Factory Method, Simple Factory) and various sources usually interpret them differently. However, the core idea is always the same.

Factory Method

The Factory Method design pattern uses a method calling the constructor. It comes in many different forms, sometimes it can use inheritance and it's mostly written against an interface. We'll show the simplest implementation here. The key principle is to separate the construction of a particular instance into another class, which prevents polluting the original class with construction code.

class Car
{
    private string maker;
    private string model;

    public Car(string maker, string model)
    {
        this.maker = maker;
        this.model = model;
    }

}

class CarFactory
{
    public Car CreateFocus()
    {
        return new Car("Ford", "Focus");
    }
}

We have a simple class with a public constructor here. We can create specific car instances as:

Car mondeo = new Car("Ford", "Mondeo");

Because we often create Focus cars in our application or they are simply more important for us and at the same time, we don't want to interfere with the Car class, we can simplify their construction to just calling a factory class method:

CarFactory factory = new CarFactory();
Car focus = factory.CreateFocus();

If you imagine that Focus has e.g. 30 attributes initialized automatically now, the pattern will definitely pay off. And even if we needed Focus just in one place in our application, moving a complex initialization into another class clarifies the logic in the class using this instance.

Factory

The Factory design pattern is more general. Basically, it's like the Factory Method, because, again, it's a method which creates our instance. However, the requirements are much less strict here. The method can be declared as static (sometimes even in the same class, as we can typically see in Java). Here's another example:

class Car
{
    private string maker;
    private string model;

    private Car(string maker, string model)
    {
        this.model = model;
        this.maker = maker;
    }

    public static Car Focus()
    {
        return new Car("Ford", "Focus");
    }
}

In this variant of the pattern, a class instance can't be created in any other way than by the factory method (but of course, the constructor can be public as well).

We create an instance as:

Car focus = Car.Focus();

The simpler implementation is the advantage of a static method right in the class. Of course, we shouldn't have too many of them in the class and they should be somehow bound to the original class' functionality. Otherwise, they should be in a separate class. Perhaps the best example of such a static method is getting the current date and time in C# .NET:

DateTime november = new DateTime(2018, 11, 24); // Specific date
DateTime today = DateTime.Now();

The Now() method returns a DateTime instance initialized to the current date and time. Such a method is directly related to the DateTime functionality and therefore it's a correct design it's in this class and it even makes sense it's static. On the other hand, with our Focus(), it's rather a deterrent example, since it doesn't have much to do with the general Car class.

Note: In C# .NET, Now() is actually a property that differs from a method in some details. In the example above, it's been shown as a method to avoid confusing programmers using other languages.

Creating instances of different classes

The return value of the Factory method doesn't have to be the same as the type of the instance being created. We can easily create an instance of a different class on each call and return only the interface that all the classes implement. As an example, we'll show a drawing program that renders different shapes on the screen. So, let's say we have a square, a circle, and a triangle, all of them implementing the IDrawable interface. We get the data from a string (for example, we're parsing a text file). According to the data provided, we decide which shape to create and return it only as an interface. The program itself doesn't know what the shape is. It just knows it can render it.

interface IDrawable
{
    void Draw();
}

class Square : IDrawable { /* ... code ... */ }
class Triangle : IDrawable { /* ... code ... */ }
class Circle : IDrawable { /* ... code ... */ }

class ShapeFactory
{
    public IDrawable Create(string type)
    {
        if (type == "Square")
            return new Square();
        else if (type == "Triangle")
            return new Triangle();
        else if (type == "Circle")
            return new Circle();
    }
}

// usage in the program
Factory factory = new ShapeFactory();
IDrawable instance = factory.Create("Square");

We can see the type is changing. The only thing the program knows is that the object can be rendered but not how to render it. It even shouldn't be its concern because it doesn't care take care of the rendering. The rendering is either a concern of a concrete class or of the objects themselves.

If we had more shapes, it'd be more useful to use reflection and create class instances dynamically based on the shape name. We must not forget to restrict the classes being instanciated to a concrete package somehow. Otherwise, the user could create pretty much anything from our application.

Návrhový vzor Factory - GOF - Creational patterns

Parameter dependencies

Sometimes we need to create a class instance, but we retrieve parameters for the constructor somewhere else in the application. We can't call the constructor since we don't have all the parameters yet and creating an uninitialized instance by e.g. a non-parametric constructor is not a good practice. If we use the Factory class, we can pass data to it gradually and it'll store them. Once there's enough data, we can create an instance. This way we don't have to worry about passing any data between the parts of the program, we only pass the Factory class instance.

Further implementations of different factory types will be added to this article. Would you like to help us with your experience with the factory? Write us a comment.


 

All articles in this section
GOF - Creational patterns
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities