The Factory Pattern

Definition
When you have a set of related concrete classes, often you're forced to write code like this:

Source: Head First Design Patterns

Often this kind of code ends up in several parts of the application making maintenance and updates more difficult and error-prone.

The Factory Pattern lets us build an interface for creating objects in a superclass while allowing subclasses to alter the type of objects that will be created. 

Implementation
We are going to create a Weapon interface and concrete classes that implement the Weapon interface.

TDD
Let's start creating some test cases. First, we need to add a test and see if any new test fails, then we update the code to make the test pass, and last we run the code again. In this case, we created a test for the operation method.

public class NewTest {
    @Test
    public void damageFlipFlop() {
        WeaponFactory wf = new WeaponFactory();
        Weapon flip_flop = wf.getWeapon(1);
        int dmg = flip_flop.damage(10);
        assertEquals(dmg, 2000);
    }

    @Test
    public void damageWiiControl() {
        WeaponFactory wf = new WeaponFactory();
        Weapon wii_control = wf.getWeapon(2);
        int dmg = wii_control.damage(10);
        assertEquals(dmg, 1000);
    }
    
    @Test
    public void damageLaptop() {
        WeaponFactory wf = new WeaponFactory();
        Weapon laptop = wf.getWeapon(3);
        int dmg = laptop.damage(10);
        assertEquals(dmg, 1500);
    }
}


Interface Weapon
Let's start creating  a Weapon interface

public interface Weapon {
    int damage(int accuracy);
}


Classes FlipFlop, WiiControl, and Laptop
Let's create some classes that would help us to implement the interface.
public class FlipFlop implements Weapon{
    @Override
    public int damage(int accuracy) {
        return 200 * accuracy;
    }
}

public class WiiControl implements Weapon{
    @Override
    public int damage(int accuracy) {
        return 100 * accuracy;
    }
}

public class Laptop implements Weapon{
    @Override
    public int damage(int accuracy) {
        return 150 * accuracy;
    }
}


Class WeaponFactory
This class would help us to generate concrete classes.

public class WeaponFactory {
    public Weapon getWeapon(int option){
        switch (option) {
            case 1:
                return new FlipFlop();
            case 2:
                return new WiiControl();
            case 3:
                return new Laptop();
            default:
                return null;
        }
    }
}


Main Class
Finally, we create the Main class which looks as follows:

public static void main(String[] args) {
    WeaponFactory wf = new WeaponFactory();
       
    //get a Flip Flop
    Weapon flip_flop = wf.getWeapon(1);
    System.out.println(flip_flop.damage(10));
       
    //get a WiiController
    Weapon wii_control = wf.getWeapon(2);
    System.out.println(wii_control.damage(10));
       
    //get a Laptop
    Weapon laptop = wf.getWeapon(3);
    System.out.println(laptop.damage(10));
}



Reference
Head First Design Patterns
by Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra
Released October 2004
Publisher(s): O'Reilly Media, Inc.

Comments