Factory method

We've already looked at the Abstract Factory and a builder. The Abstract Factory builds a family of related classes and the builder creates complicated objects using different strategies. The factory method pattern allows a class to request a new instance of an interface without the class making decisions about which implementation of the interface to use. The factory may use some strategy to select which implementation to return:

Factory method

Sometimes this strategy is simply to take a string parameter or to examine some global setting to act as a switch.

Implementation

In our example world of Westeros there are plenty of times when we would like to defer the choice of implementation to a factory. Just like the real world, Westeros has a vibrant religious culture with dozens of competing religions worshiping a wide variety of gods. When praying in each religion, different rules must be followed. Some religions demand sacrifices while others demand only that a gift be given. The prayer class doesn't want to know about all the different religions and how to construct them.

Let's start with creating a number of different gods to which prayers can be offered. This code creates three gods including a default god to whom prayers fall if no other god is specified:

let WateryGod = (function () {
  function WateryGod() {
  }
  WateryGod.prototype.prayTo = function () {
  };
  return WateryGod;
})();
Religion.WateryGod = WateryGod;
let AncientGods = (function () {
  function AncientGods() {
  }
  AncientGods.prototype.prayTo = function () {
  };
  return AncientGods;
})();
Religion.AncientGods = AncientGods;

let DefaultGod = (function () {
  function DefaultGod() {
  }
  DefaultGod.prototype.prayTo = function () {
  };
  return DefaultGod;
})();
Religion.DefaultGod = DefaultGod;

I've avoided any sort of implementation details for each god. You may imagine whatever traditions you want to populate the prayTo methods. There is also no need to ensure that each of the gods implements an IGod interface. Next we'll need a factory, which is responsible for constructing each of the different gods:

let GodFactory = (function () {
  function GodFactory() {
  }
  GodFactory.Build = function (godName) {
    if (godName === "watery")
      return new WateryGod();
    if (godName === "ancient")
      return new AncientGods();
    return new DefaultGod();
  };
  return GodFactory;
})();

You can see that in this example we're taking in a simple string to decide how to create a god. It could be done via a global or via a more complicated object. In some polytheistic religions in Westeros, gods have defined roles as gods of courage, beauty, or some other aspect. The god to which one must pray is determined by not just the religion but the purpose of the prayer. We can represent this with a GodDeterminant class as is shown here:

let GodDeterminant = (function () {
  function GodDeterminant(religionName, prayerPurpose) {
    this.religionName = religionName;
    this.prayerPurpose = prayerPurpose;
  }
  return GodDeterminant;
})();

The factory would be updated to take this class instead of the simple string.

Finally, the last step is to see how this factory would be used. It is quite simple, we just need to pass in a string that denotes which religion we wish to observe and the factory will construct the correct god and return it. This code demonstrates how to call the factory:

let Prayer = (function () {
  function Prayer() {
  }
  Prayer.prototype.pray = function (godName) {
  GodFactory.Build(godName).prayTo();
  };
  return Prayer;
})();

Once again there is certainly need for a pattern such as this in JavaScript. There are plenty of times where separating the instantiation from the use is useful. Testing the instantiation is also very simple thanks to the separation of concerns and the ability to inject a fake factory to allow testing of Prayer is also easy.

Continuing the trend of creating simpler patterns without interfaces, we can ignore the interface portion of the pattern and work directly with the types, thanks to duck typing.

Factory Method is a very useful pattern: it allows classes to defer the selection of the implementation of an instantiation to another class. This pattern is very useful when there are multiple similar implementations such as the strategy pattern (see Chapter 5, Behavioral Patterns) and is commonly used in conjunction with the Abstract Factory pattern. The Factory Method is used to build the concrete objects within a concrete implementation of the abstract factory. An Abstract Factory pattern may contain a number of Factory Methods. Factory Method is certainly a pattern that remains applicable in the land of JavaScript.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset