Introduction to factories

This post is an introduction to factories, and we will try to implement a very simple situation, that will allow us to better understand what factories do. It’s by no mean the best factory implementation, and it does not intends to be, however due to it’s simplicity it will help us to illustrate the idea. More complex factories will be discussed in other posts.

So, why factories ?

The factory pattern is used when we need to create an object but we will only know what kind of object to create during run time.

There are different ways to implement factories, and the option to choose one of them depends on the problem we want to solve, but they all share the same advantages :

  • Hiding the implementation logic behind object creation.
  • All implementation logic is removed from the client code.
  • we can change the logic of an object creation without touching the client code.
  • we code for interface rather than implementation.

The above advantages make our code less coupled and easier to maintain.

What is the main idea ?

In the real world, a factory produces goods according to market needs. Here, we are in objectland, so a factory will produce objects according to our requests, which may vary during the application run-time.

To illustrate our example we will try to solve the following problem :

Our application needs to implement a system that will send messages to our company customers, however we want to be able to send three different type of messages, Email, SMS and Fax (OK, I agree fax is old stuff, but we will use it anyway).

Depending on some kind of input, that we will only know at run-time, our application has to be able to decide which kind of message to send.

Examining our problem

The very first impulse, for a non object oriented mind will be a bunch of _if_ statements, based on that input, and job done. After all, its only 3 different type of messages !!

What if…

Next week we need to implement two more type of messages ? We will need to change all our code, and we will be facing, what I like to call an if farm, and we are half way to spaghetti code paradise. So, it does not look a very good idea.

This is the kind of problem that the factory pattern proposes to solve.

A better approach

If we look with an object oriented mind to the problem, we will spot a common element. They are all messages, only the way they are sent varies. Grouping them in a message interface seems a good starting point.

Knowing that, we can then implement an message interface, with the single method SendMessage.

Next we will write a class for each type of message, that will implement the message interface. In each of those classes we will then proceed with the actual implementation of the SendMessage method

In UML our very simple factory will look like this

Coding the UML visualization

The Message interface

Message.java
1
2
3
4
5
6
package FactoryPatternSimple;

public interface Message {

void sendMessage(String message);
}

The three message classes

Email.java
1
2
3
4
5
6
7
8
9
package FactoryPatternSimple;

public class Email implements Message {

@Override
public void sendMessage(String message) {
System.out.println("I'm sending an Email with the text : " + message);
}
}
SMS.java
1
2
3
4
5
6
7
8
9
package FactoryPatternSimple;

public class SMS implements Message {

@Override
public void sendMessage(String message) {
System.out.println("I'm sending an SMS with the text : " + message);
}
}
Fax.java
1
2
3
4
5
6
7
8
9
package FactoryPatternSimple;

public class Fax implements Message {

@Override
public void sendMessage(String message) {
System.out.println("I'm sending an FAX with the text : " + message);
}
}

In our UML diagram, we have the MessageType Enumerator. We will use it in our client code to select the type of message we want to send. We could pass Strings, but that would increase the possibility of typing errors, so the Enum, is safer.

MessageType.java
1
2
3
4
5
6
7
package FactoryPatternSimple;

public enum MessageType {
FaxMessage,
SMSMessage,
EmailMessage
}

We now have the building blocks of our factory. The way I will use in this example to illustrate the factory implementation, is a very simple approach, but my intention is to introduce the concept of what a factory does, and in my humble opinion this makes the concept easier to understand. When we discuss more complex implementations it will be simpler to understand what is happening.

MessageFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package FactoryPatternSimple;

public class MessageFactory {

public Message construct(MessageType type) {

switch (type) {

case SMSMessage:

return new SMS();

case EmailMessage:

return new Email();

case FaxMessage:

return new Fax();
}
throw new NullPointerException("Invalid Message Type");
}
}

With the interface and classes in place, we can now very easily receive the object we want to send our messages. A very simple app will do to try it out.

App.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package FactoryPatternSimple;
package FactoryPatternSimple;

public class App {

public static void main(String[] args) {
String messageText = " This is a message from our company. Many thanks";

MessageType type = MessageType.SMSMessage;
Message messageSender = new MessageFactory().construct(type);
messageSender.sendMessage(messageText);


type = MessageType.EmailMessage;
messageSender = new MessageFactory().construct(type);
messageSender.sendMessage(messageText);

type = MessageType.FaxMessage;
messageSender = new MessageFactory().construct(type);
messageSender.sendMessage(messageText);
}
}

I believe this is will help to grasp the concept behind factories, and when we discuss more complex types of factories everything will look much easier.

An example for the code in this article can be found in git-hub

Happy Coding.

Share