Factory Method


Without too much effort, we can now turn the preceding Template Method example into a Factory Method example. It's very common to implement Factory Methods in a Template Method.

In the preceding Template Method example, our createField() method doesn't return anything; it just traces out the phrase "Create Football Field." Let's update this so it creates and returns a field object. Because different games have different field types, we'll create an interface called IField that all the field classes will implement. Our interface will define a single method called drawField():

package com.peachpit.aas3wdp.factory {    public interface IField {       function drawField():void; } }


Now we'll build a FootballField class that implements the IField interface. To keep our example focused, we won't actually draw a football field to the stage, but you can fill in the blanks. Here's the basic FootballField class definition:

package com.peachpit.aas3wdp.factoryexample {    import com.peachpit.aas3wdp.factoryexample.IField;    public class FootballField implements IField {       public function drawField():void {          trace("Drawing the Football Field");       }    } }


The purpose of the Factory Method is to link up two or more separate but related class hierarchies. The first hierarchy is the AbstractGame class and its subclasses: FootballGame, BaseballGame, and BastketballGame. Our second class hierarchy is now the IField interface and the classes that implement it: FootballField, BaseballField, and BasketballField. The AbstractGame and IField objects are related, but the specific creation of these objects is determined by the game subclasses. Figure 5.1 shows how our class hierarchies match up.

Figure 5.1. The hierarchy of classes in the Factory Method example.


Now we can refactor the createField() and initialize() methods of our AbstractGame class to reflect the existence of an IField object. Our createField() method is now a Factory Method that returns an object that implements the IField interface. The initialize() method can now go one step further and call the drawField() method on the IField object, as shown here:

package com.peachpit.aas3wdp.factoryexample {    import com.peachpit.aas3wdp.factoryexample.IField;    public class AbstractGame {       // Template Method       public final function initialize():void {          var field:IField = createField();          field.drawField();          createTeam("red");          createTeam("blue");          startGame();       }       // Factory Method       public function createField():IField{          throw new Error("Abstract Method!");       }       public function createTeam(name:String):void {          throw new Error("Abstract Method!");       }       public function startGame():void {          throw new Error("Abstract Method!");       }    } }


This abstract class and template algorithm are still completely anonymous and the specific objects created are in the hands of the subclass. Let's refactor the FootballGame class now to create and return a FootballField object:

package com.peachpit.aas3wdp.factory {    import com.peachpit.aas3wdp.factory.FootballField;    import com.peachpit.aas3wdp.factory.IField;    public class FootballGame extends AbstractGame {       public override function createField():IField {          return new FootballField();       }       public override function createTeam(name:String):void {          trace("Create Football Team Named " + name);       }       public override function startGame():void {          trace("Start Football Game");       }    } }


If we run this example, we'll get the following output:

Drawing the Football Field Create Football Team Named red Create Football Team Named blue Start Football Game


A Simple Factory

The Factory Method is often misunderstood. It's not uncommon to hear people mistakenly referring to their code as following the Factory Method pattern; after examining the code, we discover that the code isn't actually a Factory Method. Early in our careers, we'd make the same mistake: we'd write classes suc as the following and think it was a Factory Method:

package com.peachpit.aas3wdp.factoryexample {    public class GameFactory {       public static function createGame(gameType:String):IGame {          switch(gameType){             case "football":                return new FootballGame();             case "baseball":                return new BaseballGame();             case "basketball":             default:                return new BasketballGame();          }       }    } }



If you think this is a Factory Method, purge that bit of information from your head and keep reading because the Factory Method is much more. In fact, the preceding example isn't even a design pattern at all. It's commonly referred to as a Simple Factory or a Parameterized Factory Method. Not to say that it isn't useful; in fact, we use this technique in Chapter 12, "State Pattern", to set the state based on a name.




Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net