Design Patterns #1 — Factories

Alex Stride
Five Minute Software
2 min readMay 24, 2020

Example situation

Logging is something that pretty much every program needs to do, but there are lots of different ways to do it. However, every logger should work in pretty much the same way; you should be able to log at a number of different levels (info, trace, debug etc.). A sensible way to structure this in code would be to create an interface, like so:

Then you are free to create as many different types of logger as you like, like this:

We like the interface patten because any other class we create can just know that it needs some implementation of `Logger` and doesn’t care about how that logger actually works. But how do you actually make sure the right type of logger gets to the right place?

What we don’t want to see

What is wrong with this? Earlier I said that other classes, like MyServer shouldn’t care about which type of logger they are using, but here MyServer can only use ConsoleLogger, and initialises this specific type of logger itself. This is an example of tight coupling and is bad.

You could pass the logger into MyServer as an argument to the constructor, which would be fine, but it just pushes the issue somewhere else, as you need to know what sort of Logger to create somewhere in your code.

Creating a Factory

It may seem obvious, but what we need is some way of choosing the right logger for the job. This is a good way to start:

What I’ve done here is created another class which does nothing but creates and returns a logger, given some input information. This is a Factory class. Simple as that.

Now we are free to write our MyServer class from before like this:

Why is this a good thing? Now, the the MyServer class really doesn’t care about what the logger is doing behind the scenes or what type of logger it is. As long as it has the right methods defined in the interface, it is happy.

Do I have to do it like this?

No. You might read about factory methods or abstract factories elsewhere on the internet. These are different implementations that make use of class inheritance to help with the Factory-like logic. I haven’t gone into those here for two main reasons:

1. I think you should minimise the use of inheritance when programming as much as you possibly can. (I’ll explain why in a later article).

2. The fundamental idea of Factories is that you have some piece of code which picks which implementation of some feature another class should be using, *so that the other class doesn’t have to care*. How you accomplish that really doesn’t matter; the goal is to have each class care about as little of the rest of the system as possible. That is the golden rule of good programming. If you can make that happen, it doesn’t matter if you did it with a class, a special method, or anything else.

--

--

Alex Stride
Five Minute Software

Software developer. Node.js handyman. React enthusiast. General follower of all things web.