工厂:根据不同条件返回不同类型的对象。
工厂方法:通过子类复写父类的(抽象)方法,返回具体对象。
模板方法:定义通用的程序执行流程,某些不确定的步骤在父类中使用抽象方法进行定义,具体实现交给子类。
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));
}
}