工厂:根据不同条件返回不同类型的对象。
工厂方法:通过子类复写父类的(抽象)方法,返回具体对象。
模板方法:定义通用的程序执行流程,某些不确定的步骤在父类中使用抽象方法进行定义,具体实现交给子类。
package pattern.factorymethod; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; /** * 工厂 * 工厂方法 * 模板方法 */ public class FactoryMethod { public static void main(String[] args) { Game game = GameFactory.createGame("Game"); game.start(); System.out.println("==================================="); Game magicGame = GameFactory.createGame("MagicGame"); magicGame.start(); } } /** * 工厂 - Factory * 负责创建对象 */ class GameFactory { public static Game createGame(String gameType) { Game game = null; if(gameType==null) { throw new IllegalArgumentException("Game can't be null"); } if(gameType.startsWith("Game")) { game = new Game(); } if(gameType.startsWith("MagicGame")) { game = new MagicGame(); } return game; } } class Game { private Set<Room> rooms = new HashSet<Room>(); public Game() { init(); } /** * 模板方法 * 通用的流程可以使用模板方法进行定制 * 还可以设置一个钩子,由子类决定哪些步骤是需要的 */ private void init() { Room room1 = MakeRoom(); Room room2 = MakeRoom(); room1.connect(room2); addRoom(room1).addRoom(room2); } private Game addRoom(Room room) { rooms.add(room); return this; } /** * 工厂方法-Factory Method * 返回一个默认的子类对象。 * 另一种常见做法是将其定义为抽象方法。 */ protected Room MakeRoom() { return new OrdinaryRoom("OrdinaryRoom"+ThreadLocalRandom.current().nextInt()); } public void start() { System.out.println("Game start: " + Arrays.toString(rooms.toArray())); } } abstract class Room { String name; int capacity = 100; abstract void connect(Room otherRoom); } class OrdinaryRoom extends Room { public OrdinaryRoom(String name) { super.name = name; } public void connect(Room otherRoom) { System.out.println(this.name + " connect to " + otherRoom.name); } } class MagicRoom extends Room { public MagicRoom(String name) { super.name = name; super.capacity = 200; } public void connect(Room otherRoom) { System.out.println(this.name + " connect to " + otherRoom.name); System.out.println("Players can see each other with network camera"); } } class MagicGame extends Game { @Override protected Room MakeRoom() { return new MagicRoom("MagicRoom"+ThreadLocalRandom.current().nextInt(10)); } }