Manus에서 모든 스킬 실행
원클릭으로
원클릭으로
원클릭으로 Manus에서 모든 스킬 실행
시작하기prototype
스타51
포크15
업데이트2026년 3월 31일 01:27
通过克隆现有实例来创建对象
설치
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
파일 탐색기
4 개 파일SKILL.md
readonly메뉴
通过克隆现有实例来创建对象
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
以聚合根为边界,包含多个相关Entity和ValueObject的集合。保证数据一致性和事务边界。
在DDD中具有唯一身份标识和生命周期的对象,通过身份而非属性值相等判断。
封装复杂对象和聚合的创建过程,将创建职责从领域对象中剥离,保证聚合创建时的不变量满足。
没有身份标识,通过属性值判断相等的对象。不可变,通常代表领域中的度量或描述。
命令查询责任分离,将数据的写入操作和读取操作分别用不同的模型处理,优化各自的性能。
将DDD战略设计应用于微服务架构,限界上下文指导服务拆分,领域事件实现服务间通信。
| name | Prototype |
| description | 通过克隆现有实例来创建对象 |
| license | MIT |
Prototype 是一种创建型设计模式,通过克隆现有实例(原型)来创建新对象,而不是通过调用构造函数。
这是Prototype模式最关键的问题!
// 浅拷贝(Shallow Copy) - 只复制引用
public class ShallowCopy {
public User clone() {
User copy = new User();
copy.id = this.id; // ✅ 基本类型复制
copy.name = this.name; // ✅ String复制(特殊)
copy.address = this.address; // ❌ 对象引用复制 → 共享!
return copy;
}
}
// 问题示例
User original = createUser();
User copy = original.clone();
copy.getAddress().setCity("Beijing"); // ❌ 修改了原对象的Address!
assert original.getAddress().getCity().equals("Beijing"); // 原对象也变了!
// 深拷贝(Deep Copy) - 递归复制所有对象
public class DeepCopy {
public User deepClone() {
User copy = new User();
copy.id = this.id;
copy.name = this.name;
copy.address = this.address.deepClone(); // ✅ 递归复制
return copy;
}
}
// 正确
User original = createUser();
User copy = original.deepClone();
copy.getAddress().setCity("Beijing"); // ✅ 只影响副本
assert original.getAddress().getCity().equals("Shanghai"); // 原对象不变!
始终使用:
触发短语:
真实场景检查:
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 创建用户对象 | ⚠️ 否 | 创建成本低,直接new即可 |
| 克隆数据库记录 | ✅ 是 | 包含许多字段和关系,克隆更简单 |
| 复制配置对象 | ✅ 是 | 配置复杂,拷贝比重新配置快 |
| 实现撤销功能 | ✅ 是 | 需要保存完整状态 |
| 游戏保存系统 | ✅ 是 | 游戏状态复杂,深拷贝很要紧 |
┌─────────────┐
│ Prototype │
│─────────────│
│ +clone() │
└──────┬──────┘
△
│
┌──────┴─────────┐
│ │
┌────┴────┐ ┌─────┴───┐
│Concrete1│ │Concrete2│
│+clone() │ │+clone() │
└─────────┘ └─────────┘
Client
↓
prototype.clone() → 快速创建副本
// ✅ 方法1: 最简单,但注意浅拷贝问题
public class User implements Cloneable {
private int id;
private String name;
private Address address; // 复杂对象
@Override
public User clone() {
try {
return (User) super.clone(); // 浅拷贝!
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
// 问题:address只复制引用
User original = new User(1, "Alice", new Address("Shanghai"));
User copy = original.clone();
copy.getAddress().setCity("Beijing"); // 原对象也变了!
优缺点:
public class User {
private int id;
private String name;
private Address address;
// 拷贝构造函数 - 推荐用于深拷贝
public User(User original) {
this.id = original.id;
this.name = original.name;
// ✅ 深拷贝Address
this.address = new Address(original.address);
}
}
public class Address {
private String city;
private String street;
public Address(Address original) {
this.city = original.city;
this.street = original.street;
}
}
// 使用
User original = new User(1, "Alice", new Address("Shanghai", "Nanjing Rd"));
User copy = new User(original); // 深拷贝
copy.getAddress().setCity("Beijing"); // 安全!不影响原对象
assert original.getAddress().getCity().equals("Shanghai"); // ✅
优缺点:
public class User {
private int id;
private String name;
private Address address;
private List<Role> roles;
// 私有构造,通过Builder创建
private User(UserBuilder builder) {
this.id = builder.id;
this.name = builder.name;
this.address = builder.address;
this.roles = builder.roles;
}
// Clone通过Builder
public User clone() {
return new UserBuilder(this).build();
}
// Builder支持部分修改
public static class UserBuilder {
private int id;
private String name;
private Address address;
private List<Role> roles;
public UserBuilder(User original) {
this(original.id);
this.name = original.name;
this.address = original.address.clone(); // 深拷贝
this.roles = new ArrayList<>(original.roles); // 深拷贝列表
}
public UserBuilder(int id) {
this.id = id;
this.roles = new ArrayList<>();
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder addRole(Role role) {
this.roles.add(role);
return this;
}
public User build() {
return new User(this);
}
}
}
// 使用:克隆并修改
User original = buildUser();
User modified = new UserBuilder(original)
.name("Bob") // 修改name
.addRole(Role.ADMIN) // 增加role
.build();
assert original.getName().equals("Alice"); // 原对象不变
assert modified.getName().equals("Bob"); // 新对象修改了
优缺点:
public class PrototypeRegistry {
private Map<String, Object> prototypes = new HashMap<>();
public void register(String key, Object prototype) {
prototypes.put(key, prototype);
}
// ✅ 深拷贝工厂方法
public <T> T clone(String key) {
Object prototype = prototypes.get(key);
if (prototype == null) {
throw new IllegalArgumentException("未知的原型: " + key);
}
return deepClone(prototype);
}
// 通用深拷贝 - 通过序列化
@SuppressWarnings("unchecked")
private <T> T deepClone(Object obj) {
try {
// 序列化 + 反序列化 = 完整深拷贝
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
T cloned = (T) ois.readObject();
ois.close();
return cloned;
} catch (Exception e) {
throw new RuntimeException("深拷贝失败", e);
}
}
}
// 使用
PrototypeRegistry registry = new PrototypeRegistry();
registry.register("admin-user", new User(999, "Admin", roleList));
User cloned = registry.clone("admin-user"); // 深拷贝
cloned.setName("Modified Admin");
assert registry.clone("admin-user").getName().equals("Admin"); // ✅ 独立
优缺点:
// 场景:频繁创建临时对象
public class ObjectPool<T> {
private Queue<T> available = new LinkedList<>();
private List<T> inUse = new ArrayList<>();
private T prototype;
public ObjectPool(T prototype, int poolSize) {
this.prototype = prototype;
for (int i = 0; i < poolSize; i++) {
available.offer(deepClone(prototype));
}
}
public T borrow() {
T obj = available.isEmpty() ?
deepClone(prototype) :
available.poll();
inUse.add(obj);
return obj;
}
public void release(T obj) {
inUse.remove(obj);
reset(obj); // 重置状态
available.offer(obj);
}
}
// 使用:数据库连接池
User templateUser = new User();
ObjectPool<User> pool = new ObjectPool<>(templateUser, 10);
User user = pool.borrow();
// 使用user
pool.release(user);
public class CommandWithPrototype {
private Stack<GameState> undoStack = new Stack<>();
private Stack<GameState> redoStack = new Stack<>();
public void executeCommand(GameCommand cmd) {
// 在执行前保存状态
GameState snapshot = gameState.deepClone();
undoStack.push(snapshot);
redoStack.clear();
// 执行命令
cmd.execute();
}
public void undo() {
if (undoStack.isEmpty()) return;
// 保存当前状态用于重做
redoStack.push(gameState.deepClone());
// 恢复之前状态
gameState = undoStack.pop();
}
public void redo() {
if (redoStack.isEmpty()) return;
undoStack.push(gameState.deepClone());
gameState = redoStack.pop();
}
}
public class DynamicObjectFactory {
private Map<Class<?>, Object> templates = new HashMap<>();
public <T> void registerTemplate(Class<T> type, T template) {
templates.put(type, template);
}
public <T> T create(Class<T> type) {
Object template = templates.get(type);
if (template == null) {
throw new IllegalArgumentException("未注册: " + type);
}
return type.cast(deepClone(template));
}
}
// 使用
DynamicObjectFactory factory = new DynamicObjectFactory();
factory.registerTemplate(User.class, defaultUser);
factory.registerTemplate(Product.class, defaultProduct);
User user = factory.create(User.class);
Product product = factory.create(Product.class);
public class CachedPrototype<T> {
private T current;
private T cached;
private long cacheTime;
private static final long TTL = 60000; // 1分钟
public CachedPrototype(T initial) {
this.current = initial;
this.cached = deepClone(initial);
}
public T getCurrent() {
return current;
}
public T getSnapshot() {
// 快速返回缓存
if (isCacheValid()) {
return deepClone(cached);
}
// 更新缓存
this.cached = deepClone(current);
this.cacheTime = System.currentTimeMillis();
return deepClone(cached);
}
private boolean isCacheValid() {
return System.currentTimeMillis() - cacheTime < TTL;
}
}
// JavaScript原型链的Java实现
public class PrototypeChain {
private Map<String, Object> own = new HashMap<>();
private PrototypeChain parent;
public PrototypeChain(PrototypeChain parentPrototype) {
this.parent = parentPrototype;
}
public Object get(String key) {
// 先查找自己的属性
if (own.containsKey(key)) {
return own.get(key);
}
// 再查找父原型
if (parent != null) {
return parent.get(key);
}
return null;
}
public void set(String key, Object value) {
own.put(key, value);
}
}
// 使用:模拟JavaScript对象
PrototypeChain objectProto = new PrototypeChain(null);
objectProto.set("toString", "Object.prototype.toString");
PrototypeChain arrayProto = new PrototypeChain(objectProto);
arrayProto.set("push", "Array.prototype.push");
assert arrayProto.get("toString") != null; // 继承
症状: 拷贝后修改嵌套对象,原对象也变了
反面示例(❌):
public class ShallowCloneBad {
private Address address;
public ShallowCloneBad clone() {
ShallowCloneBad copy = new ShallowCloneBad();
copy.address = this.address; // ❌ 浅拷贝
return copy;
}
}
// 灾难
ShallowCloneBad original = new ShallowCloneBad(new Address("Shanghai"));
ShallowCloneBad copy = original.clone();
copy.getAddress().setCity("Beijing");
assert original.getAddress().getCity().equals("Beijing"); // 原对象变了!
解决方案(✅):
public class DeepCloneGood {
private Address address;
public DeepCloneGood deepClone() {
DeepCloneGood copy = new DeepCloneGood();
copy.address = this.address.deepClone(); // ✅ 深拷贝
return copy;
}
}
// 安全
DeepCloneGood original = new DeepCloneGood(new Address("Shanghai"));
DeepCloneGood copy = original.deepClone();
copy.getAddress().setCity("Beijing");
assert original.getAddress().getCity().equals("Shanghai"); // ✅ 原对象不变
症状: 包含非Serializable字段的对象无法克隆
反面示例(❌):
public class UnserializableObject implements Serializable {
private DatabaseConnection conn; // ❌ 不能序列化!
// 序列化会失败
}
解决方案(✅):
public class SerializableWorkaround {
private DatabaseConnection conn;
// 自定义序列化逻辑
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(conn.getURL()); // 只序列化URL
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
String url = (String) ois.readObject();
this.conn = new DatabaseConnection(url); // 重建连接
}
}
// 或者用Copy Constructor
public class CopyConstructorApproach {
private DatabaseConnection conn;
public CopyConstructorApproach(CopyConstructorApproach original) {
this.conn = new DatabaseConnection(original.conn.getURL());
}
}
症状: 对象很大,深拷贝很慢
分析:
对象大小 深拷贝成本 何时使用
─────────────────────────────────
< 1MB 微不足道(<1ms) 总是用深拷贝
1-10MB 10-100ms 权衡,通常值得
10-100MB 100ms-1s 考虑浅拷贝 + COW
> 100MB > 1s 用COW或共享存储
优化方案:
// 方案1:Copy-On-Write (COW)
public class COWList<T> implements Iterable<T> {
private List<T> data;
private boolean isClone = false;
public void add(T item) {
if (isClone) {
// 已经复制,直接修改
data.add(item);
} else {
// 第一次修改时才复制
data = new ArrayList<>(data);
data.add(item);
isClone = true;
}
}
public COWList<T> clone() {
// 不复制数据,只是标记
COWList<T> copy = new COWList<>();
copy.data = this.data;
copy.isClone = false;
return copy;
}
}
// 方案2:指数退避(Exponential Backoff)
byte[] buffer = new byte[10_000_000]; // 10MB对象
byte[] copy = buffer.clone(); // 自动优化,很快
// 方案3:选择性深拷贝
public class SelectiveDeepClone {
private List<Item> items; // 通常不变,浅拷贝
private Map<String, Config> configs; // 经常变化,深拷贝
public SelectiveDeepClone clone() {
SelectiveDeepClone copy = new SelectiveDeepClone();
copy.items = this.items; // ⚠️ 浅拷贝
copy.configs = deepCopy(this.configs); // ✅ 深拷贝
return copy;
}
}
症状: 对象A包含B,B包含A,导致深拷贝死循环
反面示例(❌):
public class Node {
public Node next;
public Node deepClone() {
Node copy = new Node();
copy.next = this.next.deepClone(); // ❌ 死循环!
return copy;
}
}
// 甚至可能是间接的:A→B→C→A
解决方案(✅):
public class NodeWithCycleHandling {
public Node next;
public Node deepClone() {
return deepClone(new IdentityHashMap<>());
}
private Node deepClone(Map<Node, Node> visited) {
// 如果已访问,返回已克隆的副本
if (visited.containsKey(this)) {
return visited.get(this);
}
Node copy = new Node();
visited.put(this, copy); // 记录,防止重复
if (this.next != null) {
copy.next = this.next.deepClone(visited);
}
return copy;
}
}
// 序列化方式自动处理
class SerializableNode implements Serializable {
public SerializableNode next;
public SerializableNode deepClone() {
try {
// Java序列化自动处理循环引用
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (SerializableNode) ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}