/** * This is a demo of factory method design pattern. This pattern allows you * to abstract away the common logic for some framework. * In this case the framework is MazeGame. The common logic is in the constructor * of MazeGame. By using factory method pattern, we are able to create MazeGame * with different rooms without reimplementing the connection logic. * The 'connection logic' is really simple here (just one connect) but one can * imagine a much more complex case with many more connections. * * The concept of MazeGame is take from Wikipedia: * https://en.wikipedia.org/wiki/Factory_method_pattern * The code is original. * * @author Jason Qiu */ public abstract class MazeGame { /* * @effects Build two different MazeGame */ public static void main(String[] args) { MazeGame g1 = new OrdinaryMazeGame(); MazeGame g2 = new MagicMazeGame(); } /* * Implements the common logic for a MazeGame * * @effects Build a MazeGame with two rooms which connect to each other */ public MazeGame() { Room room1 = makeRoom(); Room room2 = makeRoom(); room1.connect(room2); } /* * Factory method */ abstract protected Room makeRoom(); } class MagicMazeGame extends MazeGame { @Override protected Room makeRoom() { return new MagicRoom(); } } class OrdinaryMazeGame extends MazeGame { @Override protected Room makeRoom() { return new OrdinaryRoom(); } } abstract class Room { protected static int numOfRooms = 0; protected int id; /* * @effects Create a room and assign an ID to it. * Also increase the total room counts. */ public Room() { numOfRooms++; id = numOfRooms; System.out.println(this + " is created "); } /* * @effects Connects this with that */ public void connect(Room that) { System.out.println(this + " is connected to " + that); } } class OrdinaryRoom extends Room { @Override public String toString() { return "OrdinaryRoom#"+id; } } class MagicRoom extends Room { @Override public String toString() { return "MagicRoom#"+id; } }