- 目的 :用原型实例指定创建对象的种类 ,并通过复制这个原型来创建新对象。
- 核心 :实现
Cloneable接口(或类似机制),提供clone()方法(深拷贝或浅拷贝需明确)来复制现有对象,避免昂贵的初始化开销。 - 场景 :在游戏开发中,大量相似对象如敌人、道具等,可以通过一个原型对象快速生成,提高效率。
首先有一个抽象创建者
java
package prototype;
import model.base.Direction;
import model.base.Door;
import model.base.Maze;
import model.base.Room;
import model.base.Wall;
public abstract class MazeGame {
// 声明若干有返回值的抽象函数
public abstract Maze MakeMaze() throws CloneNotSupportedException;
public abstract Room MakeRoom(int number) throws CloneNotSupportedException;
public abstract Wall MakeWall() throws CloneNotSupportedException;
public abstract Door MakeDoor(Room room1, Room room2) throws CloneNotSupportedException;
// 创建迷宫的模板,使用抽象工厂方法创建 迷宫组件 并 组装成完整迷宫
public Maze CreateMaze() throws CloneNotSupportedException{
// 创建迷宫组件
Maze aMaze = MakeMaze();
Room r1 = MakeRoom(1);
Room r2 = MakeRoom(2);
Door theDoor = MakeDoor(r1, r2);
// 向迷宫添加房间
aMaze.AddRoom(r1);
aMaze.AddRoom(r2);
// 设置房间1的四面墙壁和门
r1.SetSide(Direction.North, MakeWall());
r1.SetSide(Direction.East, theDoor);
r1.SetSide(Direction.South, MakeWall());
r1.SetSide(Direction.West, MakeWall());
// 设置房间2的四面墙壁和门
r2.SetSide(Direction.North, MakeWall());
r2.SetSide(Direction.East, MakeWall());
r2.SetSide(Direction.South, MakeWall());
r2.SetSide(Direction.West, theDoor);
return aMaze;
}
}
然后是具体原型工厂
java
package prototype;
import model.base.Door;
import model.base.Maze;
import model.base.Room;
import model.base.Wall;
public class MazePrototypeFactory extends MazeGame {
private Maze prototypeMaze; // 迷宫原型
private Room prototypeRoom; // 房间原型
private Wall prototypeWall; // 墙壁原型
private Door prototypeDoor; // 门原型
public MazePrototypeFactory(Maze maze, Wall wall, Room room, Door door) {
// 注入原型对象,以便克隆
this.prototypeMaze = maze;
this.prototypeRoom = room;
this.prototypeWall = wall;
this.prototypeDoor = door;
}
@Override
public Maze MakeMaze() throws CloneNotSupportedException {
return this.prototypeMaze.clone(); // 克隆原型对象
}
@Override
public Room MakeRoom(int number) throws CloneNotSupportedException {
Room room = this.prototypeRoom.clone();
room.Initialize(number);
return room;
}
@Override
public Wall MakeWall() throws CloneNotSupportedException {
return this.prototypeWall.clone();
}
@Override
public Door MakeDoor(Room room1, Room room2) throws CloneNotSupportedException {
Door door = this.prototypeDoor.clone();
door.Initialize(room1, room2);
return door;
}
}
接下来我们看怎么使用
java
package prototype;
import java.util.Iterator;
import model.base.Door;
import model.base.Maze;
import model.base.Room;
import model.base.Wall;
public class MainTest {
public static void main(String[] args) throws CloneNotSupportedException {
// 创建原型对象
Maze maze = new Maze();
Room room = new Room(1);
Wall wall = new Wall();
Door door = new Door(room, room);
// 使用原型工厂创建迷宫游戏实例
MazeGame game = new MazePrototypeFactory(maze, wall, room, door);
// 通过克隆方式创建迷宫
Maze maze2 = game.CreateMaze();
// 输出两个迷宫的房间数量进行比较
System.err.println(maze.getRoomCount()); // 0
System.err.println(maze2.getRoomCount()); // 2
Iterator<Room> iterator = maze2.iterator();
// 遍历并输出克隆迷宫中所有房间的编号
while(iterator.hasNext()){
System.err.println("RoomNumber : " + iterator.next().getRoomNumber());
}
// RoomNumber : 1
// RoomNumber : 2
}
}
最后是类图
