Factory Method
The factory method pattern
The factory method pattern is a creational pattern [GOF], which is a pattern classification concerned with flexible class building.I've seen this pattern implemented incorrectly many times, which tends to be a very large amount of methods doing nothing but returning new class objects, all lumped together, utilising the same interface.
The issue being is that to add any extra implementations usually involves changing the base class, which is breaking the open-closed principle
You cannot alter the underlying factory class!
To understand the factory pattern imagine the CSS on this HTML page, I can change the underlying styles but I can't change the structure.- pink
- blue
- orange
- Click above to change my colour
As I can't think of an implementation, I've taken the one from the book Design Patterns [GOF], if I've broken any copyright then Contact me and I'll change the code appropriately.
Here's the example:
enum Compass {
North,
East,
South,
West
}
// as I couldn't think of a concrete implementation I copied this directly from Design Patterns (GOF) for C#
// this could be abstract and the CreateMaze a default abstraction
class MazeGame {
public Maze MakeMaze() {
return new Maze();
}
public virtual Room MakeRoom(int n) {
return new Room(n);
}
public virtual Wall MakeWall() {
return new Wall();
}
public virtual Door MakeDoor(Room r1, Room r2) {
return new Door(r1, r2);
}
public Maze CreateMaze() {
Maze maze = new Maze();
Room r1 = MakeRoom(1);
Room r2 = MakeRoom(2);
Door door = new Door(r1, r2);
maze.AddRoom(r1);
maze.AddRoom(r2);
r1.SetSide(Compass.North, MakeWall());
r1.SetSide(Compass.East, door);
r1.SetSide(Compass.South, MakeWall());
r1.SetSide(Compass.West, MakeWall());
r2.SetSide(Compass.North, MakeWall());
r2.SetSide(Compass.East, MakeWall());
r2.SetSide(Compass.South, MakeWall());
r2.SetSide(Compass.West, door);
return maze;
}
}
And a different implementation that uses the default(base) but requires different objects:
North,
East,
South,
West
}
// as I couldn't think of a concrete implementation I copied this directly from Design Patterns (GOF) for C#
// this could be abstract and the CreateMaze a default abstraction
class MazeGame {
public Maze MakeMaze() {
return new Maze();
}
public virtual Room MakeRoom(int n) {
return new Room(n);
}
public virtual Wall MakeWall() {
return new Wall();
}
public virtual Door MakeDoor(Room r1, Room r2) {
return new Door(r1, r2);
}
public Maze CreateMaze() {
Maze maze = new Maze();
Room r1 = MakeRoom(1);
Room r2 = MakeRoom(2);
Door door = new Door(r1, r2);
maze.AddRoom(r1);
maze.AddRoom(r2);
r1.SetSide(Compass.North, MakeWall());
r1.SetSide(Compass.East, door);
r1.SetSide(Compass.South, MakeWall());
r1.SetSide(Compass.West, MakeWall());
r2.SetSide(Compass.North, MakeWall());
r2.SetSide(Compass.East, MakeWall());
r2.SetSide(Compass.South, MakeWall());
r2.SetSide(Compass.West, door);
return maze;
}
}
class BombedMazeGame : MazeGame {
public override Room MakeRoom(int n) {
return new RoomWithABomb(n);
}
public override Wall MakeWall() {
return new BombedWall();
}
}
public override Room MakeRoom(int n) {
return new RoomWithABomb(n);
}
public override Wall MakeWall() {
return new BombedWall();
}
}
Summary
That's the factory method pattern and like all beautiful and powerful structures it's incredible simple and
because of it's simplicity I haven't created a large running example.