文章目录
什么是原型模式?
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过新建类的方式。原型模式允许一个对象再创建另外一个可定制的对象,无需知道创建的细节。
核心思想
原型模式的核心思想是:通过复制(克隆)现有对象来创建新对象,而不是通过new关键字实例化。 这就像细胞的自我复制,基于一个模板快速生成新的个体。
生活中的原型模式
想象一下印章的使用:
- 你有一个原始印章(原型)
- 想要多个相同的图案,不需要重新雕刻
- 只需要用印泥复制(克隆)即可
- 每个复制品都和原始印章一样
印章就是原型,复制过程就是克隆!
模式结构
原型模式包含三个核心角色:
- 抽象原型(Prototype):声明克隆方法的接口
- 具体原型(Concrete Prototype):实现克隆方法的具体类
- 客户端(Client):通过克隆方法创建新对象
基础示例:图形复制系统
1. 抽象原型接口
/**
* 图形接口 - 抽象原型
* 声明克隆方法
*/
public interface Shape extends Cloneable {
/**
* 克隆方法
*/
Shape clone();
/**
* 绘制图形
*/
void draw();
/**
* 获取图形信息
*/
String getInfo();
/**
* 设置颜色
*/
void setColor(String color);
/**
* 获取颜色
*/
String getColor();
}
2. 具体原型类
import java.util.ArrayList;
import java.util.List;
/**
* 圆形 - 具体原型
*/
public class Circle implements Shape {
private int radius;
private String color;
private List<String> tags;
public Circle(int radius, String color) {
this.radius = radius;
this.color = color;
this.tags = new ArrayList<>();
System.out.println("🔄 创建新的圆形对象(构造函数调用)");
// 模拟复杂的初始化过程
simulateComplexInitialization();
}
@Override
public Shape clone() {
System.out.println("⚡ 通过克隆创建圆形副本");
try {
Circle clone = (Circle) super.clone();
// 对引用类型进行深拷贝
clone.tags = new ArrayList<>(this.tags);
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
@Override
public void draw() {
System.out.printf("🎯 绘制圆形: 半径=%d, 颜色=%s, 标签=%s%n",
radius, color, tags);
}
@Override
public String getInfo() {
return String.format("圆形[半径=%d, 颜色=%s, 标签=%s]", radius, color, tags);
}
@Override
public void setColor(String color) {
this.color = color;
}
@Override
public String getColor() {
return color;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void addTag(String tag) {
this.tags.add(tag);
}
public List<String> getTags() {
return new ArrayList<>(tags);
}
/**
* 模拟复杂的初始化过程
*/
private void simulateComplexInitialization() {
try {
Thread.sleep(100); // 模拟耗时操作
// 模拟从配置文件或数据库加载数据
tags.add("几何图形");
tags.add("对称图形");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 矩形 - 具体原型
*/
public class Rectangle implements Shape {
private int width;
private int height;
private String color;
private List<Point> points;
public Rectangle(int width, int height, String color) {
this.width = width;
this.height = height;
this.color = color;
this.points = new ArrayList<>();
initializePoints();
System.out.println("🔄 创建新的矩形对象(构造函数调用)");
simulateComplexInitialization();
}
@Override
public Shape clone() {
System.out.println("⚡ 通过克隆创建矩形副本");
try {
Rectangle clone = (Rectangle) super.clone();
// 深拷贝引用类型
clone.points = new ArrayList<>();
for (Point point : this.points) {
clone.points.add(point.clone());
}
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
@Override
public void draw() {
System.out.printf("📐 绘制矩形: 宽=%d, 高=%d, 颜色=%s%n", width, height, color);
}
@Override
public String getInfo() {
return String.format("矩形[宽=%d, 高=%d, 颜色=%s, 顶点数=%d]",
width, height, color, points.size());
}
@Override
public void setColor(String color) {
this.color = color;
}
@Override
public String getColor() {
return color;
}
public void setWidth(int width) {
this.width = width;
initializePoints();
}
public void setHeight(int height) {
this.height = height;
initializePoints();
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
/**
* 初始化顶点坐标
*/
private void initializePoints() {
points.clear();
points.add(new Point(0, 0));
points.add(new Point(width, 0));
points.add(new Point(width, height));
points.add(new Point(0, height));
}
/**
* 模拟复杂的初始化过程
*/
private void simulateComplexInitialization() {
try {
Thread.sleep(150); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 点坐标类 - 支持克隆
*/
class Point implements Cloneable {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public Point clone() {
try {
return (Point) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("点坐标克隆失败", e);
}
}
@Override
public String toString() {
return String.format("(%d,%d)", x, y);
}
}
3. 图形注册表(原型管理器)
import java.util.HashMap;
import java.util.Map;
/**
* 图形注册表 - 原型管理器
* 管理和提供各种原型对象
*/
public class ShapeRegistry {
private static ShapeRegistry instance;
private final Map<String, Shape> prototypes;
private ShapeRegistry() {
this.prototypes = new HashMap<>();
initializePrototypes();
}
public static ShapeRegistry getInstance() {
if (instance == null) {
instance = new ShapeRegistry();
}
return instance;
}
/**
* 初始化原型对象
*/
private void initializePrototypes() {
System.out.println("🎨 初始化图形原型库...");
// 创建各种预定义的原型
prototypes.put("red_circle", new Circle(10, "红色"));
prototypes.put("blue_circle", new Circle(15, "蓝色"));
prototypes.put("green_rectangle", new Rectangle(20, 10, "绿色"));
prototypes.put("yellow_rectangle", new Rectangle(30, 20, "黄色"));
// 为原型添加标签
((Circle) prototypes.get("red_circle")).addTag("标准圆形");
((Circle) prototypes.get("blue_circle")).addTag("大圆形");
((Rectangle) prototypes.get("green_rectangle")).addTag("小矩形");
((Rectangle) prototypes.get("yellow_rectangle")).addTag("大矩形");
System.out.println("✅ 图形原型库初始化完成");
}
/**
* 根据类型获取原型副本
*/
public Shape getShape(String type) {
Shape prototype = prototypes.get(type);
if (prototype == null) {
throw new IllegalArgumentException("未知的图形类型: " + type);
}
return prototype.clone();
}
/**
* 注册新的原型
*/
public void registerPrototype(String type, Shape prototype) {
prototypes.put(type, prototype);
System.out.println("📝 注册新原型: " + type);
}
/**
* 显示所有可用的原型
*/
public void displayAvailablePrototypes() {
System.out.println("\n📚 可用的图形原型:");
System.out.println("-".repeat(50));
prototypes.forEach((key, shape) -> {
System.out.printf("🔑 %-20s -> %s%n", key, shape.getInfo());
});
}
}
4. 客户端使用
/**
* 图形编辑器客户端
*/
public class ShapeEditor {
public static void main(String[] args) {
System.out.println("=== 原型模式演示 - 图形编辑器 ===\n");
// 获取图形注册表
ShapeRegistry registry = ShapeRegistry.getInstance();
// 显示可用原型
registry.displayAvailablePrototypes();
System.out.println("\n🎯 原型克隆演示:");
System.out.println("-".repeat(50));
// 演示1:基础克隆
demonstrateBasicCloning(registry);
// 演示2:性能对比
demonstratePerformanceComparison();
// 演示3:自定义修改
demonstrateCustomization(registry);
// 演示4:动态注册原型
demonstrateDynamicRegistration(registry);
}
/**
* 演示基础克隆
*/
private static void demonstrateBasicCloning(ShapeRegistry registry) {
System.out.println("1. 基础克隆演示:");
// 从原型库获取图形副本
Shape circle1 = registry.getShape("red_circle");
Shape circle2 = registry.getShape("red_circle");
Shape rectangle1 = registry.getShape("green_rectangle");
System.out.println("\n📋 克隆结果:");
System.out.println("圆形1: " + circle1.getInfo());
System.out.println("圆形2: " + circle2.getInfo());
System.out.println("矩形1: " + rectangle1.getInfo());
// 验证是否是不同对象
System.out.println("\n🔍 对象验证:");
System.out.println("圆形1和圆形2是同一个对象吗? " + (circle1 == circle2));
System.out.println("圆形1和圆形2内容相同吗? " + circle1.getInfo().equals(circle2.getInfo()));
}
/**
* 演示性能对比
*/
private static void demonstratePerformanceComparison() {
System.out.println("\n2. 性能对比演示:");
System.out.println("-".repeat(40));
// 测试使用new创建对象
long startTime = System.currentTimeMillis();
testWithNewOperator();
long newTime = System.currentTimeMillis() - startTime;
// 测试使用克隆创建对象
startTime = System.currentTimeMillis();
testWithClone();
long cloneTime = System.currentTimeMillis() - startTime;
System.out.println("\n⏱️ 性能对比结果:");
System.out.printf("使用new操作符: %d ms%n", newTime);
System.out.printf("使用克隆方法: %d ms%n", cloneTime);
System.out.printf("性能提升: %.1f%%%n",
(1 - (double) cloneTime / newTime) * 100);
}
private static void testWithNewOperator() {
System.out.println("测试使用new创建100个圆形...");
for (int i = 0; i < 100; i++) {
new Circle(10, "红色"); // 每次都要执行复杂初始化
}
}
private static void testWithClone() {
System.out.println("测试使用克隆创建100个圆形...");
Circle prototype = new Circle(10, "红色"); // 只初始化一次
for (int i = 0; i < 100; i++) {
prototype.clone(); // 快速克隆
}
}
/**
* 演示自定义修改
*/
private static void demonstrateCustomization(ShapeRegistry registry) {
System.out.println("\n3. 克隆后自定义演示:");
System.out.println("-".repeat(40));
// 获取原型副本
Shape circle = registry.getShape("blue_circle");
Shape rectangle = registry.getShape("yellow_rectangle");
System.out.println("原始图形:");
circle.draw();
rectangle.draw();
// 修改克隆后的对象
circle.setColor("紫色");
((Circle) circle).setRadius(25);
((Circle) circle).addTag("自定义圆形");
rectangle.setColor("橙色");
((Rectangle) rectangle).setWidth(40);
((Rectangle) rectangle).setHeight(30);
System.out.println("\n修改后的图形:");
circle.draw();
rectangle.draw();
// 验证原型未被修改
Shape originalCircle = registry.getShape("blue_circle");
System.out.println("\n🔍 验证原型完整性:");
System.out.println("原型: " + originalCircle.getInfo());
System.out.println("克隆: " + circle.getInfo());
System.out.println("原型和克隆相同吗? " + originalCircle.getInfo().equals(circle.getInfo()));
}
/**
* 演示动态注册原型
*/
private static void demonstrateDynamicRegistration(ShapeRegistry registry) {
System.out.println("\n4. 动态注册原型演示:");
System.out.println("-".repeat(40));
// 创建自定义图形并注册为原型
Circle customCircle = new Circle(8, "粉色");
customCircle.addTag("自定义");
customCircle.addTag("特殊图形");
registry.registerPrototype("pink_small_circle", customCircle);
// 使用新注册的原型
Shape clonedCircle1 = registry.getShape("pink_small_circle");
Shape clonedCircle2 = registry.getShape("pink_small_circle");
System.out.println("使用新原型创建的图形:");
clonedCircle1.draw();
clonedCircle2.draw();
// 显示更新后的原型库
registry.displayAvailablePrototypes();
}
}
完整示例:游戏角色系统
让我们通过一个更复杂的游戏角色系统来深入理解原型模式。
1. 游戏角色原型
import java.util.*;
/**
* 游戏角色接口 - 抽象原型
*/
public interface GameCharacter extends Cloneable {
GameCharacter clone();
void display();
String getCharacterInfo();
void setLevel(int level);
void setHealth(int health);
}
/**
* 战士角色 - 具体原型
*/
class Warrior implements GameCharacter {
private String name;
private int level;
private int health;
private List<String> skills;
private Equipment equipment;
private Map<String, Integer> attributes;
public Warrior(String name) {
this.name = name;
this.level = 1;
this.health = 100;
this.skills = new ArrayList<>();
this.equipment = new Equipment();
this.attributes = new HashMap<>();
initializeWarrior();
System.out.println("⚔️ 创建新的战士角色: " + name);
simulateComplexInitialization();
}
@Override
public GameCharacter clone() {
System.out.println("⚡ 克隆战士角色: " + name);
try {
Warrior clone = (Warrior) super.clone();
// 深拷贝所有引用类型
clone.skills = new ArrayList<>(this.skills);
clone.equipment = this.equipment.clone();
clone.attributes = new HashMap<>(this.attributes);
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("战士克隆失败", e);
}
}
@Override
public void display() {
System.out.printf("🧔 战士 %s [等级%d, 生命值%d]%n", name, level, health);
System.out.printf(" 技能: %s%n", skills);
System.out.printf(" 装备: %s%n", equipment);
System.out.printf(" 属性: %s%n", attributes);
}
@Override
public String getCharacterInfo() {
return String.format("战士%s(等级%d,生命%d,技能%d个)",
name, level, health, skills.size());
}
@Override
public void setLevel(int level) {
this.level = level;
}
@Override
public void setHealth(int health) {
this.health = health;
}
public void addSkill(String skill) {
this.skills.add(skill);
}
public void setAttribute(String attribute, int value) {
this.attributes.put(attribute, value);
}
public void equipWeapon(String weapon) {
this.equipment.setWeapon(weapon);
}
public void equipArmor(String armor) {
this.equipment.setArmor(armor);
}
/**
* 初始化战士属性
*/
private void initializeWarrior() {
skills.add("重击");
skills.add("防御");
attributes.put("力量", 15);
attributes.put("敏捷", 8);
attributes.put("体力", 12);
equipment.setWeapon("长剑");
equipment.setArmor("锁子甲");
}
/**
* 模拟复杂的初始化过程
*/
private void simulateComplexInitialization() {
try {
Thread.sleep(200); // 模拟从数据库加载数据等操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 法师角色 - 具体原型
*/
class Mage implements GameCharacter {
private String name;
private int level;
private int health;
private List<String> spells;
private Equipment equipment;
private Map<String, Integer> attributes;
private int mana;
public Mage(String name) {
this.name = name;
this.level = 1;
this.health = 80;
this.mana = 100;
this.spells = new ArrayList<>();
this.equipment = new Equipment();
this.attributes = new HashMap<>();
initializeMage();
System.out.println("🧙 创建新的法师角色: " + name);
simulateComplexInitialization();
}
@Override
public GameCharacter clone() {
System.out.println("⚡ 克隆法师角色: " + name);
try {
Mage clone = (Mage) super.clone();
// 深拷贝
clone.spells = new ArrayList<>(this.spells);
clone.equipment = this.equipment.clone();
clone.attributes = new HashMap<>(this.attributes);
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("法师克隆失败", e);
}
}
@Override
public void display() {
System.out.printf("🧙 法师 %s [等级%d, 生命值%d, 魔法值%d]%n",
name, level, health, mana);
System.out.printf(" 法术: %s%n", spells);
System.out.printf(" 装备: %s%n", equipment);
System.out.printf(" 属性: %s%n", attributes);
}
@Override
public String getCharacterInfo() {
return String.format("法师%s(等级%d,生命%d,魔法%d,法术%d个)",
name, level, health, mana, spells.size());
}
@Override
public void setLevel(int level) {
this.level = level;
}
@Override
public void setHealth(int health) {
this.health = health;
}
public void addSpell(String spell) {
this.spells.add(spell);
}
public void setMana(int mana) {
this.mana = mana;
}
/**
* 初始化法师属性
*/
private void initializeMage() {
spells.add("火球术");
spells.add("寒冰箭");
attributes.put("智力", 18);
attributes.put("精神", 12);
attributes.put("体力", 6);
equipment.setWeapon("法杖");
equipment.setArmor("布甲");
}
private void simulateComplexInitialization() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 装备类 - 支持克隆
*/
class Equipment implements Cloneable {
private String weapon;
private String armor;
private String accessory;
public Equipment() {
this.weapon = "无";
this.armor = "无";
this.accessory = "无";
}
@Override
public Equipment clone() {
try {
return (Equipment) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("装备克隆失败", e);
}
}
public void setWeapon(String weapon) {
this.weapon = weapon;
}
public void setArmor(String armor) {
this.armor = armor;
}
public void setAccessory(String accessory) {
this.accessory = accessory;
}
@Override
public String toString() {
return String.format("武器:%s, 护甲:%s, 饰品:%s", weapon, armor, accessory);
}
}
2. 角色管理器
import java.util.HashMap;
import java.util.Map;
/**
* 角色管理器 - 原型管理器
*/
public class CharacterManager {
private static CharacterManager instance;
private final Map<String, GameCharacter> characterPrototypes;
private CharacterManager() {
this.characterPrototypes = new HashMap<>();
initializePrototypes();
}
public static CharacterManager getInstance() {
if (instance == null) {
instance = new CharacterManager();
}
return instance;
}
/**
* 初始化角色原型
*/
private void initializePrototypes() {
System.out.println("🎮 初始化角色原型库...");
// 创建预定义的角色原型
Warrior warrior = new Warrior("标准战士");
warrior.setLevel(5);
warrior.addSkill("旋风斩");
characterPrototypes.put("standard_warrior", warrior);
Mage mage = new Mage("标准法师");
mage.setLevel(5);
mage.addSpell("暴风雪");
characterPrototypes.put("standard_mage", mage);
// 创建高级角色原型
Warrior eliteWarrior = new Warrior("精英战士");
eliteWarrior.setLevel(10);
eliteWarrior.setHealth(150);
eliteWarrior.addSkill("雷霆一击");
eliteWarrior.equipWeapon("巨斧");
eliteWarrior.equipArmor("板甲");
characterPrototypes.put("elite_warrior", eliteWarrior);
Mage eliteMage = new Mage("精英法师");
eliteMage.setLevel(10);
eliteMage.setHealth(120);
eliteMage.setMana(200);
eliteMage.addSpell("陨石术");
characterPrototypes.put("elite_mage", eliteMage);
System.out.println("✅ 角色原型库初始化完成");
}
/**
* 获取角色副本
*/
public GameCharacter getCharacter(String type) {
GameCharacter prototype = characterPrototypes.get(type);
if (prototype == null) {
throw new IllegalArgumentException("未知的角色类型: " + type);
}
return prototype.clone();
}
/**
* 注册新原型
*/
public void registerPrototype(String type, GameCharacter prototype) {
characterPrototypes.put(type, prototype);
System.out.println("📝 注册新角色原型: " + type);
}
/**
* 显示所有可用原型
*/
public void displayAvailablePrototypes() {
System.out.println("\n📚 可用的角色原型:");
System.out.println("-".repeat(50));
characterPrototypes.forEach((key, character) -> {
System.out.printf("🔑 %-20s -> %s%n", key, character.getCharacterInfo());
});
}
/**
* 创建自定义角色
*/
public GameCharacter createCustomCharacter(String type, String name) {
GameCharacter character = getCharacter(type);
// 这里可以添加自定义逻辑,比如重命名等
return character;
}
}
3. 游戏客户端
/**
* 游戏客户端
*/
public class GameClient {
public static void main(String[] args) {
System.out.println("=== 原型模式演示 - 游戏角色系统 ===\n");
CharacterManager manager = CharacterManager.getInstance();
// 显示可用原型
manager.displayAvailablePrototypes();
System.out.println("\n🎯 角色克隆演示:");
System.out.println("-".repeat(50));
// 创建玩家队伍
System.out.println("👥 创建玩家队伍:");
GameCharacter player1 = manager.getCharacter("standard_warrior");
GameCharacter player2 = manager.getCharacter("standard_mage");
GameCharacter player3 = manager.getCharacter("elite_warrior");
GameCharacter player4 = manager.getCharacter("elite_mage");
// 显示队伍成员
player1.display();
player2.display();
player3.display();
player4.display();
System.out.println("\n🔄 创建副本并自定义:");
System.out.println("-".repeat(40));
// 创建副本并自定义
GameCharacter customWarrior = manager.getCharacter("standard_warrior");
customWarrior.setLevel(8);
customWarrior.setHealth(130);
((Warrior) customWarrior).addSkill("英勇跳跃");
((Warrior) customWarrior).equipWeapon("传说之剑");
GameCharacter customMage = manager.getCharacter("standard_mage");
customMage.setLevel(7);
customMage.setHealth(95);
((Mage) customMage).addSpell("时空扭曲");
((Mage) customMage).setMana(180);
System.out.println("自定义后的角色:");
customWarrior.display();
customMage.display();
System.out.println("\n🎪 大规模角色创建演示:");
System.out.println("-".repeat(40));
// 演示大规模创建NPC
createNPCArmy(manager);
System.out.println("\n⏱️ 性能优势演示:");
demonstratePerformanceAdvantage();
}
/**
* 创建NPC军队
*/
private static void createNPCArmy(CharacterManager manager) {
System.out.println("创建NPC军队(50个战士,30个法师)...");
long startTime = System.currentTimeMillis();
// 使用原型模式快速创建大量NPC
for (int i = 1; i <= 50; i++) {
GameCharacter soldier = manager.getCharacter("standard_warrior");
// 可以在这里进行个性化设置
if (i % 10 == 0) {
soldier.setLevel(3); // 每10个有一个小队长
}
}
for (int i = 1; i <= 30; i++) {
GameCharacter mage = manager.getCharacter("standard_mage");
if (i % 5 == 0) {
mage.setLevel(4); // 每5个有一个高级法师
}
}
long duration = System.currentTimeMillis() - startTime;
System.out.printf("✅ 创建80个NPC完成,耗时: %d ms%n", duration);
}
/**
* 演示性能优势
*/
private static void demonstratePerformanceAdvantage() {
System.out.println("性能对比:创建100个复杂角色");
// 测试传统方式
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
new Warrior("战士" + i); // 每次都要完整初始化
}
long traditionalTime = System.currentTimeMillis() - startTime;
// 测试原型模式
Warrior prototype = new Warrior("原型战士");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
prototype.clone(); // 基于原型快速克隆
}
long prototypeTime = System.currentTimeMillis() - startTime;
System.out.printf("传统方式: %d ms%n", traditionalTime);
System.out.printf("原型模式: %d ms%n", prototypeTime);
System.out.printf("性能提升: %.1f%%%n",
(1 - (double) prototypeTime / traditionalTime) * 100);
}
}
深拷贝 vs 浅拷贝
/**
* 深拷贝和浅拷贝演示
*/
public class CopyDemo {
public static void main(String[] args) {
System.out.println("=== 深拷贝 vs 浅拷贝演示 ===\n");
// 创建原始对象
OriginalObject original = new OriginalObject("原始数据");
original.addItem("项目A");
original.addItem("项目B");
System.out.println("原始对象: " + original);
// 浅拷贝
OriginalObject shallowCopy = original.shallowCopy();
shallowCopy.setName("浅拷贝数据");
shallowCopy.addItem("项目C");
System.out.println("\n浅拷贝后:");
System.out.println("原始对象: " + original);
System.out.println("浅拷贝: " + shallowCopy);
// 深拷贝
OriginalObject deepCopy = original.deepCopy();
deepCopy.setName("深拷贝数据");
deepCopy.addItem("项目D");
System.out.println("\n深拷贝后:");
System.out.println("原始对象: " + original);
System.out.println("深拷贝: " + deepCopy);
}
}
class OriginalObject implements Cloneable {
private String name;
private List<String> items;
private Date createTime;
public OriginalObject(String name) {
this.name = name;
this.items = new ArrayList<>();
this.createTime = new Date();
}
// 浅拷贝
public OriginalObject shallowCopy() {
try {
return (OriginalObject) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("浅拷贝失败", e);
}
}
// 深拷贝
public OriginalObject deepCopy() {
try {
OriginalObject copy = (OriginalObject) super.clone();
// 对引用类型进行深拷贝
copy.items = new ArrayList<>(this.items);
copy.createTime = (Date) this.createTime.clone();
return copy;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("深拷贝失败", e);
}
}
public void setName(String name) {
this.name = name;
}
public void addItem(String item) {
this.items.add(item);
}
@Override
public String toString() {
return String.format("OriginalObject{name='%s', items=%s, createTime=%s}",
name, items, createTime);
}
}
原型模式的优点
1. 性能提升
// 避免重复执行昂贵的初始化操作
// 特别适合创建成本高的对象
2. 简化对象创建
// 客户端不需要知道具体创建细节
// 通过简单克隆即可获得新对象
3. 动态配置
// 可以在运行时动态添加或删除原型
// 灵活性高
原型模式的缺点
1. 深拷贝复杂性
// 需要正确实现深拷贝
// 对于复杂对象图,实现可能很复杂
2. 需要支持克隆
// 所有需要克隆的类都要实现Cloneable接口
// 可能需要重写clone方法
适用场景
- 对象创建成本较高时
- 需要避免使用与产品类层次平行的工厂类层次时
- 一个类的实例只能有几个不同状态组合时
- 需要动态加载类时
最佳实践
1. 正确实现深拷贝
@Override
public Object clone() {
try {
MyClass clone = (MyClass) super.clone();
// 对每个引用类型进行深拷贝
clone.listField = new ArrayList<>(this.listField);
clone.mapField = new HashMap<>(this.mapField);
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("克隆失败", e);
}
}
2. 考虑使用拷贝构造函数
public MyClass(MyClass other) {
this.field1 = other.field1;
this.listField = new ArrayList<>(other.listField);
// ...
}
3. 使用原型管理器
// 集中管理原型对象
// 提供统一的访问接口
总结
原型模式就像是对象的"复印机",可以快速创建对象的副本,避免重复的初始化工作。
核心价值:
- 提高对象创建性能
- 简化复杂对象的创建过程
- 提供动态的对象创建机制
使用场景:
- 对象创建成本高时
- 需要创建大量相似对象时
- 需要避免繁琐的初始化过程时
简单记忆:
对象创建太麻烦?原型模式来帮忙!
就像复印机一样,一键复制真便当。
掌握原型模式,能够让你在面对复杂对象创建时游刃有余,显著提升系统性能!
2275

被折叠的 条评论
为什么被折叠?



