Contents

Design Patterns - Creational - Abstract Factory

An introduction to the Creational D.P. called Abstract Factory.

For this article, will be good to have some knowledge on Object Orientation Programming, and Java, that is the programming language that I will use to demonstrate the code.

As this series of articles are intended to be easy to read and to understand, covering the basics of all design patterns, I will show some basic examples of nowadays real-life problems. Go grab some coffee before reading, and I wish you a good reading.

Let’s suppose we are creating a stream platform, which will contain different plans, like

  • basic plan
  • gold plan
  • premium super mega deluxe plan

And these plans are nothing more that a bunch of channels, combination of some movies and series from some platforms that each plan have, like

  • basic plan = TV plan (with 30 channels, the free ones) + movies plan (with limited catalog) + series plan (with limited catalog)
  • gold plan = TV plan (with 50 channels) + movies plan (with limited catalog, but bigger than basic) + series plan (with limited catalog, but bigger than basic)
  • super mega hiper plan = TV plan (with all the 99 channels) + movies plan (with unlimited) + series plan (with unlimited catalog)

You won’t sell together things that doesn’t make a plan. You can only sell specific combinations that the sells department have defined, like the combinations above.

We can create the small classes (TV, movies, etc) first

public class FreeTVChannels {
  //constructor

  //fields

  // getters
  // setters
}

public class FreeTVChannelsPlus {
  //constructor

  //fields

  // getters
  // setters
}

public class UnlimitedTVChannels {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedMovies {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedMoviesPlus {
  //constructor

  //fields

  // getters
  // setters
}

public class UnlimitedMovies {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedSeries {
  //constructor

  //fields
  
  // getters
  // setters
}

public class LimitedSeriesPlus {
  //constructor

  //fields
  
  // getters
  // setters
}

public class UnlimitedSeries {
  //constructor

  //fields
  
  // getters
  // setters
}

And now, we create the concrete products, those that will be sell to our customers

public class Product {
  //constructor

  //fields

  // getters
  // setters
}

And our main class

public class Main {
  public static void main(String[] args) {
    Product product = getProduct("basicPlan");
  }

  private Product getProduct(String productString) {
    FreeTVChannels freeTVChannels = new FreeTVChannels();
    FreeTVChannelsPlus freeTVChannelsPlus = new FreeTVChannelsPlus();
    UnlimitedTVChannels unlimitedTVChannels = new UnlimitedTVChannels();

    LimitedMovies limitedMovies = new LimitedMovies();
    LimitedMoviesPlus limitedMoviesPlus = new LimitedMoviesPlus();
    UnlimitedMovies unlimitedMovies = new UnlimitedMovies();

    LimitedSeries limitedSeries = new LimitedSeries();
    LimitedSeriesPlus limitedSeriesPlus = new LimitedSeriesPlus();
    UnlimitedSeries unlimitedSeries = new UnlimitedSeries();

    final Product product;

    if (productString == "basicPlan") product = new Product(freeTVChannels, limitedMovies, limitedSeries);
    else if (productString == "goldPlan") product = Product(freeTVChannelsPlus, limitedMoviesPlus, limitedSeriesPlus);
    else if (productString == "premiumSuperMegaDeluxePlan") product = new Product(unlimitedTVChannels, unlimitedMovies, unlimitedSeries);
    else throw new Exception("not a valid plan");

    return product;
  }
}

The big problem here is, imagine if this combinations grow up. You will need to change a lot on your code, change the client to add more combinations or change the existing ones. You will violate the Single Responsibility principle because your client knows too much.

With the abstract factory, you will avoid this strong connection between the client and the concrete products.

We can use the same small classes (TV, movies, etc), but using interfaces to define the type

public class FreeTVChannels extends TVChannels {
  //constructor

  //fields

  // getters
  // setters
}

public class FreeTVChannelsPlus extends TVChannels {
  //constructor

  //fields

  // getters
  // setters
}

public class UnlimitedTVChannels extends TVChannels {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedMovies extends Movies {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedMoviesPlus extends Movies {
  //constructor

  //fields

  // getters
  // setters
}

public class UnlimitedMovies extends Movies {
  //constructor

  //fields

  // getters
  // setters
}

public class LimitedSeries extends Series {
  //constructor

  //fields
  
  // getters
  // setters
}

public class LimitedSeriesPlus extends Series {
  //constructor

  //fields
  
  // getters
  // setters
}

public class UnlimitedSeries extends Series {
  //constructor

  //fields
  
  // getters
  // setters
}

And now, we create the concrete products, those that will be sell to our customers

public class BasicPlan extends Product {
  //constructor

  //fields

  // getters
  // setters
}

public class GoldPlan extends Product {
  //constructor

  //fields

  // getters
  // setters
}

public class SuperMegaHiperPlan extends Product {
  //constructor

  //fields

  // getters
  // setters
}

Now our abstract factory

public interface ProductFactory {

}

And, the implementations

public class BasicPlanProductFactory implements ProductFactory {

}

public class GoldPlanProductFactory implements ProductFactory {

}

public class SuperMegaHiperPlanProductFactory implements ProductFactory {

}

And our main class

public class Main {
  public static void main(String[] args) {
    Product product = getProduct("basicPlan");
  }

  private Product getProduct(String productString) {

    final ProductFactory productFactory;
    
    if (productString == "basicPlan") productFactory = new BasicPlanProductFactory();
    else if (productString == "goldPlan") productFactory = new GoldPlanProductFactory();
    else if (productString == "premiumSuperMegaDeluxePlan") productFactory = new SuperMegaHiperPlanProductFactory();
    else throw new Exception("not a valid plan");

    productFactory.createTVChannels();
    productFactory.createMovies();
    productFactory.createSeries();

    Product product = new Product(productFactory.createTVChannels(), productFactory.createMovies(), productFactory.createSeries());
    
    return product;
  }
}