五、原型模式

  • 目的 :用原型实例指定创建对象的种类 ,并通过复制这个原型来创建新对象。
  • 核心 :实现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
	}
}

最后是类图

相关推荐
学长毕设4 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw6 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号6 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场7 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠7 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David8 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放8 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户3721574261358 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java
小嘉丶学长9 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节