Design Patterns is an important subject to any developer and so you can expect a post about them every once in a while.
The Factory Method is an object-oriented creational design pattern that deals with the problem of creating objects without having to specify the exact class of object that should be created. Let’s build a simple example to illustrate the concept.
We’ll create a class that will deal with names. That class will store the first and last names and will provide methods to get them.
class Name:
def __init__(self):
self.first = ""
self.last = ""
def get_first(self):
return self.first
def get_last(self):
return self.last
Now, when we create a class to deal with names, we will pass it a string and that string can come in many formatss. For the sake of simplicity of this example we will be limited to two formats:
- “FirstName LastName”, which will be handled by the FirstFirst class;
- “LastName,FirstName”, which will be handled by the LastFirst class.
The code below implements those classes and they will extend our Name class.
class FirstFirst(Name):
def __init__(self, s):
i = s.rfind(" ")
if i > -1:
self.first = s[0:i]
self.last = s[i+1:len(s)]
else:
self.first = ""
self.last = s
class LastFirst(Name):
def __init__(self, s):
i = s.rfind(",")
if i > -1:
self.first = s[i+1:len(s)]
self.last = s[0:i]
else:
self.first = ""
self.last = s
The code itself is pretty simple and by now we’re only missing our factory. So let’s see how we will go about that.
class NameFactory:
def get_name(self, s):
i = s.find(",")
if i > -1:
return LastFirst(s)
else:
return FirstFirst(s)
So, what’s happening here? We’re simply identifying, based on the provided string, which of the actual classes should be used to create the object. The code using this factory doesn’t really care which class it’s being used. Let’s make it more clear with an example.
def test():
name_factory = NameFactory()
name1 = name_factory.get_name("Castro,Ricardo")
name2 = name_factory.get_name("Pedro Teixeira")
print name1.get_first(), name1.get_last()
print name2.get_first(), name2.get_last()
We’re creating a test function that creates a factory and uses that same factory to create two Name objects. If we run it:
$ python test.py
Ricardo Castro
Pedro Teixeira
This test code has no idea which class is dealing with each name string. And it doesn’t have to! The only thing that this code needs is a factory that gives back a Name object that it can use.
Note: The code presented here is based on the Java code available in Design Patterns Java Companion, by James W. Cooper. For a more extensive analysis of this concept you can read that or any book about Design Patterns that, of course, details the Factory Method design pattern.