Sunday, February 7, 2016

Abstract Factory or Factory Method?

Today I would like to tell you about Factory Method Pattern and Abstract Factory Pattern. The purpose of the article is to help you recognize places where one of them should be used.

What will we talk about?

Those patterns are one of the Creational Patterns and as the name suggest their main responsibility is creating the objects. However, we are using them in different situations.

In Wikipedia you can find the following definitions:
[...] the Factory Method Pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes.".
Ok, when we are familiar with theory, we can look how it works in practice.

Factory Method as a Named Constructor

Factory Method Pattern can help you make your code more readable.

Take a look at the class Person:
public class Person {
   public Person(Person mum, Person dad) {
       // some code
   }

   public Person() {
       // some code
   }
}

Is it clear for you why we have got two constructors and why both of them create a valid object?

Would it be more obvious if the code looked like the one below?
public class Person {
   public static Person withParents(Person mum, Person dad) {
       // some code
   }

   public static Person anOrphan() {
       // some code
   }
  
   private Person() {}
}

Is it better?

I believe that you saw classes with more constructors. Was it always easy to find out what all the differences between created objects were? Don’t you think that using Named Constructors is the solution that can save time of a person who will have to work with the code?

Stay focused on interface

It’s good practice to focus on generalization rather than on specification. Factory Method Pattern can help you with that.

If you have a group of classes that implements the same interface, you can create them with factory methods not with new keyword.
Thanks to this, only the interface and class responsible for creation would be published:
public interface Currency {}

class Zloty implements Currency {}
class Euro implements Currency {}
class Dolar implements Currency {}

public class Currencies {
   public static Currency dollar() {
       return new Dollar();
   }
  
   public static Currency euro() {
       return new Euro();
   }
  
   public static Currency zloty() {
       return new Zloty();
   }
}

In the given example only the Currency interface and Currencies class will be used outside the package. This gives you much more flexibility in case of any change. The only thing you need to worry about is the API of Currency and Currencies classes. Everything else, from the perspective of the developer who will use this code, is irrelevant.

Give a choice

If there are groups of objects organized around one concept, but creation of the specific instances depends on chosen option it can be worth considering using the Abstract Factory Pattern.

In the example below we give a choice to specify components’ theme. Depending on the choice, we are using a specific factory to create the needed objects, as follows:
public interface OSComponents {
   Window aWindow();
   Menu aMenu();
   Panel aPanel();
}

public interface Window {}
public interface Panel {}
public interface Menu {}

public class UnixComponents implements OSComponents {
   @Override
   public Window aWindow() {
       return new UnixWindow();
   }

   @Override
   public Menu aMenu() {
       return new UnixMenu();
   }

   @Override
   public Panel aPanel() {
       return new UnixPanel();
   }
}

public class WindowsComponents implements OSComponents {
   // code
}

public class iOSComponents implements OSComponents {
   // code
}

Now we can focus only on interface provided by OSComponents interface. We don’t care at all about any specific implementation.

Summary

You should use Abstract Factory Pattern where creation of specific objects depends on a choice. You are creating a required factory object and passing it further. The code that manipulates on it is interested only in interfaces.

Factory Method Pattern should be used when you want to explain what logic stands behind creating an object in given state (Named Constructor) or when you want to publish only an interface, not entire group of classes that implements it.

Hopefully this article will help you with making a decisions when you should use a particular solution.

But maybe this is not all? If you noticed something that I missed, please share it by posting your comment below.


No comments:

Post a Comment