Patterns 101: The Factory

By Joe Hubert
Page 3 of 4

The Pattern Approach

So I decide I'm not going to modify my application as I've indicated above. First, I'm going to redesign it with what I consider a better approach:

  • I'm going to replace the switch statement with a class that will function as a "factory".
  • I'm going to replace the show(Day)Tasks() methods with individual classes that extend a new base class called DayTasks. (A whole class for each day of the week? And it just prints out a task list? Yeah, probably overkill for this example, but bear with me; it makes sense.)

So I will replace MainProcedural.java with these classes:

Listing 2: MainPatterns.java - this is the central class
import java.util.Date;

public class MainPatterns {
    public static void main(String[] args) {
        Date date = new Date();
        int weekday = -1;
        MainPatterns taskMgr = new MainPatterns();
        DayTasks taskDisplayer;

        //-- Allow the weekday to be set by a parameter so we can test the program
        if (args.length >0 ) {
            try {
                weekday = Integer.parseInt(args[0]);
            }
            catch (Exception e) {
                System.out.println("Parameter must be 1 - 7");
            }
        }
        else {
            weekday =  date.getDay();
        }
        //-- Retrieve the appropriate DayTasks from the factory:
        taskDisplayer = DayTaskFactory.getDayTaskHandler(weekday);

        try {
            taskDisplayer.showTasks();
        }
        catch (Exception e) {
            System.out.println("No handler found. Weekday: " + weekday);
        }
    }
}
Listing 3: DayTaskFactory.java - the factory class that will return us a specific class depending on what day of the week it is.
public class DayTaskFactory {

    public static DayTasks getDayTaskHandler(int weekday) {
        DayTasks  taskDisplayer;

        switch (weekday) {
            case 1:
                taskDisplayer = new MondayTasks();
                break;
            case 2:
                taskDisplayer = new TuesdayTasks();
                break;
            case 3:
                taskDisplayer = new WednesdayTasks();
                break;
            case 4:
                taskDisplayer = new ThursdayTasks();
                break;
            case 5:
                taskDisplayer = new FridayTasks();
                break;
            default:
                taskDisplayer = null;
        }
        return taskDisplayer;
    }
}
Listing 4: DayTasks.java - an abstract base class. The core class will deal with objects of this type. We could have just as easily made DayTasks.java an interface.
public abstract class DayTasks {
    public abstract void showTasks();
}
Listing 5a: MondayTasks.java
public class MondayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Monday: Take trash to the curb");
    }
}
Listing 5b: TuesdayTasks.java
public class TuesdayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Tuesday: Put out recyclables");
    }
}
Listing 5c: WednesdayTasks.java
public class WednesdayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Wednesday: Watch \"Lost\"");
    }
}
Listing 5d: ThursdayTasks.java
public class ThursdayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Thursday: Take trash to the curb");
    }
}
Listing 5e: FridayTasks.java
public class FridayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Friday: Buy beer");
    }
}

These classes will each extend DayTasks.java and manage the specific message for the day of the week.

When I run this application, my output is identical to my procedural design. That's not a surprise. We don't employ a pattern approach for the application end-user's benefit (not directly, anyway).


Question: What can I accomplish with design patterns that can't be done with a more traditional procedural approach?

Answer: If you're talking about application functionality, the answer is: probably nothing. Patterns deal with how you organize your code. The example in this article demonstrates how the procedural approach builds a routine and the pattern approach builds a framework. This pattern approach lends itself to simpler extensibility because decision-making is handled in the factory and operational specifics are handled in the DayTasks subclasses. With the procedural approach, the separation of functionality wasn't organized (or separated) as well.

So my initial modification plans:

  • Change the switch statement to include cases for Saturday and Sunday.
  • Write new methods to handle the task displays: showSaturdayTasks()and showSundayTasks.

Are replaced with these plans:

  • Create classes that print messages for Saturday and Sunday
  • Modify the factory to also return these classes

Here's the modified factory:

Listing 6: DayTaskFactory.java
public class DayTaskFactory {

    public static DayTasks getDayTaskHandler(int weekday) {
        DayTasks  taskDisplayer;

        switch (weekday) {
            case 0:
                taskDisplayer = new SundayTasks();
                break;
            case 1:
                taskDisplayer = new MondayTasks();
                break;
            case 2:
                taskDisplayer = new TuesdayTasks();
                break;
            case 3:
                taskDisplayer = new WednesdayTasks();
                break;
            case 4:
                taskDisplayer = new ThursdayTasks();
                break;
            case 5:
                taskDisplayer = new FridayTasks();
                break;
            case 6:
                taskDisplayer = new SaturdayTasks();
                break;
            default:
                taskDisplayer = null;
        }
        return taskDisplayer;
    }
}

And here are the new classes for Saturday and Sunday

Listing 7a: SaturdayTasks.java
public class SaturdayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Saturday: Cut the lawn");
    }
}
Listing 7b: SundayTasks.java
public class SundayTasks extends DayTasks {
    public void showTasks() {
        System.out.println("Sunday: Call Mom");
    }
}
Feedback

Articles
Factory 101

Strategy 101