当前位置: 首页 > news >正文

设计模式-原型模式详解

原型模式详解

目录

  1. 原型模式简介
  2. 核心流程
  3. 重难点分析
  4. Spring中的源码分析
  5. 具体使用场景
  6. 面试高频点
  7. 使用总结

原型模式简介

定义

原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有实例来创建新的实例,而不是通过新建类的方式。原型模式允许一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。

核心思想

  • 克隆创建:通过克隆现有对象来创建新对象
  • 避免重复创建:避免重复创建相似对象的开销
  • 动态配置:可以在运行时动态配置对象
  • 简化创建过程:简化复杂对象的创建过程

模式结构

  • Prototype(抽象原型类):声明克隆自身的接口
  • ConcretePrototype(具体原型类):实现克隆自身的操作
  • Client(客户端):使用原型实例克隆出新的实例

核心流程

原型模式流程图

克隆过程
原型层次
浅克隆
深克隆
属性复制
抽象原型接口
具体原型A
具体原型B
客户端
请求克隆对象
原型对象
调用clone方法
创建新实例
复制属性值
返回克隆对象
客户端使用克隆对象

基本实现流程

1. 定义抽象原型接口
// 抽象原型接口
public interface Prototype {Prototype clone();
}
2. 实现具体原型类
// 具体原型类
public class ConcretePrototype implements Prototype {private String name;private int value;private List<String> items;public ConcretePrototype(String name, int value, List<String> items) {this.name = name;this.value = value;this.items = new ArrayList<>(items);}// 复制构造函数public ConcretePrototype(ConcretePrototype prototype) {this.name = prototype.name;this.value = prototype.value;this.items = new ArrayList<>(prototype.items);}@Overridepublic Prototype clone() {return new ConcretePrototype(this);}// getter和setter方法public String getName() { return name; }public void setName(String name) { this.name = name; }public int getValue() { return value; }public void setValue(int value) { this.value = value; }public List<String> getItems() { return items; }public void setItems(List<String> items) { this.items = items; }@Overridepublic String toString() {return "ConcretePrototype{" +"name='" + name + '\'' +", value=" + value +", items=" + items +'}';}
}
3. 客户端使用
public class Client {public static void main(String[] args) {// 创建原型对象List<String> items = Arrays.asList("item1", "item2", "item3");ConcretePrototype prototype = new ConcretePrototype("原型", 100, items);// 克隆对象ConcretePrototype clone1 = (ConcretePrototype) prototype.clone();ConcretePrototype clone2 = (ConcretePrototype) prototype.clone();// 修改克隆对象clone1.setName("克隆1");clone1.setValue(200);clone1.getItems().add("item4");clone2.setName("克隆2");clone2.setValue(300);clone2.getItems().add("item5");// 输出结果System.out.println("原型: " + prototype);System.out.println("克隆1: " + clone1);System.out.println("克隆2: " + clone2);}
}

重难点分析

重难点1:浅克隆与深克隆

问题描述

如何正确实现浅克隆和深克隆,避免克隆过程中的问题。

解决方案
// 浅克隆实现
public class ShallowClone implements Cloneable {private String name;private int value;private List<String> items;public ShallowClone(String name, int value, List<String> items) {this.name = name;this.value = value;this.items = items;}@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone(); // 浅克隆}// getter和setter方法
}// 深克隆实现
public class DeepClone implements Cloneable {private String name;private int value;private List<String> items;public DeepClone(String name, int value, List<String> items) {this.name = name;this.value = value;this.items = new ArrayList<>(items);}@Overridepublic Object clone() throws CloneNotSupportedException {DeepClone cloned = (DeepClone) super.clone();// 深克隆:复制引用对象cloned.items = new ArrayList<>(this.items);return cloned;}// getter和setter方法
}// 使用序列化实现深克隆
public class SerializableClone implements Serializable {private String name;private int value;private List<String> items;public SerializableClone(String name, int value, List<String> items) {this.name = name;this.value = value;this.items = new ArrayList<>(items);}public SerializableClone deepClone() {try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);return (SerializableClone) ois.readObject();} catch (Exception e) {throw new RuntimeException("深克隆失败", e);}}// getter和setter方法
}

重难点2:原型注册表管理

问题描述

如何管理多个原型对象,提供统一的克隆接口。

解决方案
// 原型注册表
public class PrototypeRegistry {private static final Map<String, Prototype> prototypes = new HashMap<>();static {// 注册默认原型prototypes.put("default", new ConcretePrototype("默认", 0, new ArrayList<>()));prototypes.put("template1", new ConcretePrototype("模板1", 100, Arrays.asList("item1", "item2")));prototypes.put("template2", new ConcretePrototype("模板2", 200, Arrays.asList("item3", "item4")));}public static void registerPrototype(String name, Prototype prototype) {prototypes.put(name, prototype);}public static Prototype getPrototype(String name) {Prototype prototype = prototypes.get(name);if (prototype == null) {throw new IllegalArgumentException("原型不存在: " + name);}return prototype.clone();}public static List<String> getPrototypeNames() {return new ArrayList<>(prototypes.keySet());}
}// 使用示例
public class PrototypeRegistryDemo {public static void main(String[] args) {// 注册自定义原型PrototypeRegistry.registerPrototype("custom", new ConcretePrototype("自定义", 300, Arrays.asList("item5", "item6")));// 获取原型ConcretePrototype prototype1 = (ConcretePrototype) PrototypeRegistry.getPrototype("template1");ConcretePrototype prototype2 = (ConcretePrototype) PrototypeRegistry.getPrototype("custom");System.out.println("原型1: " + prototype1);System.out.println("原型2: " + prototype2);}
}

重难点3:原型模式的线程安全

问题描述

在多线程环境下,如何确保原型模式的线程安全。

解决方案
// 线程安全的原型模式
public class ThreadSafePrototype implements Cloneable {private final String name;private final int value;private final List<String> items;private final Object lock = new Object();public ThreadSafePrototype(String name, int value, List<String> items) {this.name = name;this.value = value;this.items = new ArrayList<>(items);}@Overridepublic synchronized Object clone() throws CloneNotSupportedException {ThreadSafePrototype cloned = (ThreadSafePrototype) super.clone();// 深克隆cloned.items = new ArrayList<>(this.items);return cloned;}public ThreadSafePrototype cloneSafely() {synchronized (lock) {try {return (ThreadSafePrototype) clone();} catch (CloneNotSupportedException e) {throw new RuntimeException("克隆失败", e);}}}// getter方法public String getName() { return name; }public int getValue() { return value; }public List<String> getItems() { return new ArrayList<>(items); }
}// 使用ConcurrentHashMap的原型注册表
public class ConcurrentPrototypeRegistry {private static final ConcurrentHashMap<String, Prototype> prototypes = new ConcurrentHashMap<>();public static void registerPrototype(String name, Prototype prototype) {prototypes.put(name, prototype);}public static Prototype getPrototype(String name) {Prototype prototype = prototypes.get(name);if (prototype == null) {throw new IllegalArgumentException("原型不存在: " + name);}return prototype.clone();}
}

重难点4:原型模式的性能优化

问题描述

如何优化原型模式的性能,避免频繁的对象创建。

解决方案
// 对象池模式结合原型模式
public class PrototypePool {private final Queue<Prototype> pool = new ConcurrentLinkedQueue<>();private final Prototype prototype;private final int maxSize;public PrototypePool(Prototype prototype, int maxSize) {this.prototype = prototype;this.maxSize = maxSize;}public Prototype acquire() {Prototype obj = pool.poll();if (obj == null) {obj = prototype.clone();}return obj;}public void release(Prototype obj) {if (pool.size() < maxSize) {// 重置对象状态resetObject(obj);pool.offer(obj);}}private void resetObject(Prototype obj) {// 重置对象状态的具体实现if (obj instanceof Resettable) {((Resettable) obj).reset();}}
}// 可重置接口
public interface Resettable {void reset();
}// 缓存原型对象
public class CachedPrototype implements Prototype {private static final Map<String, Prototype> cache = new ConcurrentHashMap<>();private final String key;private final Prototype prototype;public CachedPrototype(String key, Prototype prototype) {this.key = key;this.prototype = prototype;}@Overridepublic Prototype clone() {return cache.computeIfAbsent(key, k -> prototype.clone());}
}

Spring中的源码分析

Spring Bean的原型模式

// AbstractBeanFactory中的原型Bean处理
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}@SuppressWarnings("unchecked")protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {String beanName = transformedBeanName(name);Object bean;// 尝试从缓存中获取单例BeanObject sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else {// 检查Bean定义是否存在BeanDefinition mbd = getMergedBeanDefinition(beanName);if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);} catch (BeansException ex) {destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);} else if (mbd.isPrototype()) {// 原型Bean:每次创建新实例Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);} else {// 其他作用域的BeanString scopeName = mbd.getScope();Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);} finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);} catch (IllegalStateException ex) {throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread", ex);}}}return adaptBeanInstance(name, bean, requiredType);}
}

Spring的ObjectUtils.cloneIfPossible

// ObjectUtils中的克隆方法
public class ObjectUtils {@SuppressWarnings("unchecked")public static <T> T cloneIfPossible(T obj) {if (obj instanceof Cloneable) {try {return (T) obj.getClass().getMethod("clone").invoke(obj);} catch (Exception ex) {// 克隆失败,返回原对象return obj;}}return obj;}public static <T> T clone(T obj) {if (obj == null) {return null;}if (obj instanceof Cloneable) {try {return (T) obj.getClass().getMethod("clone").invoke(obj);} catch (Exception ex) {throw new RuntimeException("克隆失败", ex);}}throw new IllegalArgumentException("对象不支持克隆: " + obj.getClass());}
}

Spring的BeanWrapper

// BeanWrapper中的属性复制
public class BeanWrapperImpl extends PropertyAccessorFactory implements BeanWrapper {@Overridepublic void copyProperties(Object source, Object target) {copyProperties(source, target, null, (String[]) null);}@Overridepublic void copyProperties(Object source, Object target, String... ignoreProperties) {copyProperties(source, target, null, ignoreProperties);}private void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) {Assert.notNull(source, "Source must not be null");Assert.notNull(target, "Target must not be null");Class<?> actualEditable = target.getClass();if (editable != null) {if (!editable.isInstance(target)) {throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]");}actualEditable = editable;}PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : Collections.emptyList());for (PropertyDescriptor targetPd : targetPds) {Method writeMethod = targetPd.getWriteMethod();if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null) {Method readMethod = sourcePd.getReadMethod();if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {try {if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}Object value = readMethod.invoke(source);if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}writeMethod.invoke(target, value);} catch (Throwable ex) {throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);}}}}}}
}

具体使用场景

1. 配置对象克隆

// 配置对象
public class DatabaseConfig implements Cloneable {private String host;private int port;private String database;private String username;private String password;private Map<String, String> properties;public DatabaseConfig(String host, int port, String database, String username, String password) {this.host = host;this.port = port;this.database = database;this.username = username;this.password = password;this.properties = new HashMap<>();}@Overridepublic DatabaseConfig clone() {try {DatabaseConfig cloned = (DatabaseConfig) super.clone();// 深克隆cloned.properties = new HashMap<>(this.properties);return cloned;} catch (CloneNotSupportedException e) {throw new RuntimeException("克隆失败", e);}}// getter和setter方法public String getHost() { return host; }public void setHost(String host) { this.host = host; }public int getPort() { return port; }public void setPort(int port) { this.port = port; }public String getDatabase() { return database; }public void setDatabase(String database) { this.database = database; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public Map<String, String> getProperties() { return properties; }public void setProperties(Map<String, String> properties) { this.properties = properties; }
}// 配置管理器
public class ConfigManager {private static final Map<String, DatabaseConfig> configs = new HashMap<>();static {// 默认配置DatabaseConfig defaultConfig = new DatabaseConfig("localhost", 3306, "test", "root", "password");configs.put("default", defaultConfig);// 开发环境配置DatabaseConfig devConfig = defaultConfig.clone();devConfig.setDatabase("dev_db");configs.put("dev", devConfig);// 生产环境配置DatabaseConfig prodConfig = defaultConfig.clone();prodConfig.setHost("prod-server");prodConfig.setDatabase("prod_db");prodConfig.setUsername("prod_user");prodConfig.setPassword("prod_password");configs.put("prod", prodConfig);}public static DatabaseConfig getConfig(String environment) {DatabaseConfig config = configs.get(environment);if (config == null) {throw new IllegalArgumentException("配置不存在: " + environment);}return config.clone();}
}

2. 文档模板克隆

// 文档模板
public class DocumentTemplate implements Cloneable {private String title;private String content;private List<String> sections;private Map<String, String> metadata;public DocumentTemplate(String title, String content) {this.title = title;this.content = content;this.sections = new ArrayList<>();this.metadata = new HashMap<>();}@Overridepublic DocumentTemplate clone() {try {DocumentTemplate cloned = (DocumentTemplate) super.clone();// 深克隆cloned.sections = new ArrayList<>(this.sections);cloned.metadata = new HashMap<>(this.metadata);return cloned;} catch (CloneNotSupportedException e) {throw new RuntimeException("克隆失败", e);}}public DocumentTemplate createDocument(String title, String content) {DocumentTemplate document = this.clone();document.setTitle(title);document.setContent(content);return document;}// getter和setter方法public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }public String getContent() { return content; }public void setContent(String content) { this.content = content; }public List<String> getSections() { return sections; }public void setSections(List<String> sections) { this.sections = sections; }public Map<String, String> getMetadata() { return metadata; }public void setMetadata(Map<String, String> metadata) { this.metadata = metadata; }
}// 文档管理器
public class DocumentManager {private static final Map<String, DocumentTemplate> templates = new HashMap<>();static {// 创建模板DocumentTemplate reportTemplate = new DocumentTemplate("报告模板", "这是一个报告模板");reportTemplate.getSections().add("摘要");reportTemplate.getSections().add("正文");reportTemplate.getSections().add("结论");reportTemplate.getMetadata().put("author", "系统");reportTemplate.getMetadata().put("version", "1.0");templates.put("report", reportTemplate);DocumentTemplate letterTemplate = new DocumentTemplate("信件模板", "这是一个信件模板");letterTemplate.getSections().add("称呼");letterTemplate.getSections().add("正文");letterTemplate.getSections().add("结尾");letterTemplate.getMetadata().put("type", "formal");templates.put("letter", letterTemplate);}public static DocumentTemplate createDocument(String templateName, String title, String content) {DocumentTemplate template = templates.get(templateName);if (template == null) {throw new IllegalArgumentException("模板不存在: " + templateName);}return template.createDocument(title, content);}
}

3. 游戏对象克隆

// 游戏对象
public class GameObject implements Cloneable {private String name;private int health;private int level;private List<String> skills;private Map<String, Object> properties;public GameObject(String name, int health, int level) {this.name = name;this.health = health;this.level = level;this.skills = new ArrayList<>();this.properties = new HashMap<>();}@Overridepublic GameObject clone() {try {GameObject cloned = (GameObject) super.clone();// 深克隆cloned.skills = new ArrayList<>(this.skills);cloned.properties = new HashMap<>(this.properties);return cloned;} catch (CloneNotSupportedException e) {throw new RuntimeException("克隆失败", e);}}public GameObject createInstance(String name) {GameObject instance = this.clone();instance.setName(name);return instance;}// getter和setter方法public String getName() { return name; }public void setName(String name) { this.name = name; }public int getHealth() { return health; }public void setHealth(int health) { this.health = health; }public int getLevel() { return level; }public void setLevel(int level) { this.level = level; }public List<String> getSkills() { return skills; }public void setSkills(List<String> skills) { this.skills = skills; }public Map<String, Object> getProperties() { return properties; }public void setProperties(Map<String, Object> properties) { this.properties = properties; }
}// 游戏对象工厂
public class GameObjectFactory {private static final Map<String, GameObject> prototypes = new HashMap<>();static {// 创建原型GameObject playerPrototype = new GameObject("玩家", 100, 1);playerPrototype.getSkills().add("攻击");playerPrototype.getSkills().add("防御");playerPrototype.getProperties().put("class", "warrior");prototypes.put("player", playerPrototype);GameObject enemyPrototype = new GameObject("敌人", 50, 1);enemyPrototype.getSkills().add("攻击");enemyPrototype.getProperties().put("class", "monster");prototypes.put("enemy", enemyPrototype);}public static GameObject createObject(String type, String name) {GameObject prototype = prototypes.get(type);if (prototype == null) {throw new IllegalArgumentException("对象类型不存在: " + type);}return prototype.createInstance(name);}
}

面试高频点

面试知识点思维导图

原型模式面试点
基本概念
实现方式
重难点
Spring应用
设计原则
实际应用
克隆创建
避免重复创建
动态配置
简化创建过程
Prototype抽象原型类
ConcretePrototype具体原型类
Client客户端
Cloneable接口
浅克隆vs深克隆
原型注册表管理
线程安全问题
性能优化
Bean原型作用域
ObjectUtils克隆
BeanWrapper属性复制
配置对象克隆
单一职责
开闭原则
依赖倒置
接口隔离
配置对象克隆
文档模板克隆
游戏对象克隆
缓存对象克隆

1. 原型模式的基本概念

问题:什么是原型模式?

答案要点:

  • 通过复制现有实例来创建新的实例
  • 属于创建型设计模式
  • 避免重复创建相似对象的开销
  • 简化复杂对象的创建过程
问题:原型模式有哪些角色?

答案要点:

  • Prototype(抽象原型类):声明克隆自身的接口
  • ConcretePrototype(具体原型类):实现克隆自身的操作
  • Client(客户端):使用原型实例克隆出新的实例

2. 实现方式相关

问题:如何实现原型模式?

答案要点:

// 1. 实现Cloneable接口
public class ConcretePrototype implements Cloneable {private String name;private int value;public ConcretePrototype(String name, int value) {this.name = name;this.value = value;}@Overridepublic ConcretePrototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException("克隆失败", e);}}
}// 2. 使用复制构造函数
public class ConcretePrototype {private String name;private int value;public ConcretePrototype(String name, int value) {this.name = name;this.value = value;}// 复制构造函数public ConcretePrototype(ConcretePrototype prototype) {this.name = prototype.name;this.value = prototype.value;}public ConcretePrototype clone() {return new ConcretePrototype(this);}
}

3. 重难点问题

问题:浅克隆和深克隆的区别?

答案要点:

  • 浅克隆:只复制基本类型和引用,不复制引用对象
  • 深克隆:复制所有属性,包括引用对象
  • 实现方式:浅克隆使用super.clone(),深克隆需要手动复制引用对象
  • 注意事项:深克隆需要递归复制所有引用对象
问题:如何实现深克隆?

答案要点:

// 1. 手动实现深克隆
@Override
public Object clone() throws CloneNotSupportedException {DeepClone cloned = (DeepClone) super.clone();// 深克隆:复制引用对象cloned.items = new ArrayList<>(this.items);cloned.metadata = new HashMap<>(this.metadata);return cloned;
}// 2. 使用序列化实现深克隆
public DeepClone deepClone() {try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(this);ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);return (DeepClone) ois.readObject();} catch (Exception e) {throw new RuntimeException("深克隆失败", e);}
}

4. Spring中的应用

问题:Spring中如何使用原型模式?

答案要点:

// 1. 原型Bean
@Component
@Scope("prototype")
public class PrototypeBean {// Bean实现
}// 2. 获取原型Bean
@Autowired
private ApplicationContext applicationContext;public PrototypeBean getPrototypeBean() {return applicationContext.getBean(PrototypeBean.class);
}// 3. 使用ObjectUtils克隆
Object cloned = ObjectUtils.cloneIfPossible(original);

5. 设计原则相关

问题:原型模式体现了哪些设计原则?

答案要点:

  • 单一职责:原型只负责克隆操作
  • 开闭原则:可以添加新的原型类型
  • 依赖倒置:依赖抽象而不是具体实现
  • 接口隔离:客户端只依赖需要的接口

6. 实际应用场景

问题:原型模式适用于哪些场景?

答案要点:

  • 配置对象:数据库配置、系统配置等
  • 文档模板:报告模板、信件模板等
  • 游戏对象:角色、道具、场景等
  • 缓存对象:需要频繁创建相似对象
  • 复杂对象:创建成本较高的复杂对象

使用总结

原型模式的优势

  1. 性能优化:避免重复创建相似对象的开销
  2. 简化创建:简化复杂对象的创建过程
  3. 动态配置:可以在运行时动态配置对象
  4. 代码复用:通过克隆实现代码复用

原型模式的缺点

  1. 深克隆复杂:深克隆实现复杂,容易出错
  2. 内存开销:需要维护原型对象,占用内存
  3. 循环引用:深克隆时可能遇到循环引用问题
  4. 性能问题:深克隆可能影响性能

使用建议

  1. 简单对象:只用于创建简单对象,复杂对象考虑其他模式
  2. 深克隆:需要深克隆时,考虑使用序列化方式
  3. 线程安全:多线程环境下注意线程安全
  4. 性能考虑:权衡克隆成本和创建成本

最佳实践

  1. 实现Cloneable接口:正确实现Cloneable接口
  2. 深克隆实现:需要深克隆时,手动复制引用对象
  3. 异常处理:正确处理CloneNotSupportedException
  4. 文档注释:为克隆方法添加详细的文档注释
  5. 单元测试:为克隆功能编写单元测试

与其他模式的对比

  1. 与工厂模式:原型模式通过克隆创建,工厂模式通过新建创建
  2. 与建造者模式:原型模式克隆现有对象,建造者模式构建新对象
  3. 与单例模式:原型模式创建多个实例,单例模式创建唯一实例

原型模式是一种有用的创建型设计模式,特别适用于需要创建大量相似对象、配置对象克隆、模板对象克隆等场景。通过合理使用原型模式,可以大大提高系统的性能和灵活性。

http://www.dtcms.com/a/398254.html

相关文章:

  • ESP8266与CEM5826-M11毫米波雷达传感器的动态检测系统
  • [原创]怎么用qq邮箱订阅arxiv.org?
  • 设计模式-中介者模式详解
  • 【探寻C++之旅】第十四章:简单实现set和map
  • 牛客:机器翻译
  • 20250925的学习笔记
  • 域名不同网站程序相同wordpress多门户网站
  • 淘宝API商品详情接口全解析:从基础数据到深度挖掘
  • 【低代码】百度开源amis
  • 求推荐专业的网站建设开发免费商城
  • java面试day4 | 微服务、Spring Cloud、注册中心、负载均衡、CAP、BASE、分布式接口幂等性、xxl-job
  • 高QE sCMOS相机在SIM超分辨显微成像中的应用
  • C++设计模式之创建型模式:原型模式(Prototype)
  • Node.js/Python 调用 1688 API 实时拉取商品信息的实现方案
  • OpenLayers地图交互 -- 章节九:拖拽框交互详解
  • 浅谈 Kubernetes 微服务部署架构
  • 媒体资源云优客seo排名公司
  • 企业如何构建全面防护体系,应对勒索病毒与恶意软件攻击?
  • 【重磅发布】《特色产业数据要素价值化研究报告》
  • fast-lio有ros2版本吗?
  • PWM 冻结模式 模式1 强制输出有效电平 强制输出无效电平 设置有效电平 实现闪烁灯
  • 系统分析师-软件工程-信息系统开发方法面向对象原型化方法面向服务快速应用开发
  • Linux的写作日记:Linux基础开发工具(一)
  • 做响应网站的素材网站有哪些怎么在年报网站做简易注销
  • C++中的initializer_list
  • 关于营销型网站建设的建议促进房地产市场健康发展
  • PHP验证码生成与测试
  • 漫谈<无头浏览器技术>:二、演进之路
  • .NET驾驭Word之力:智能文档处理 - 查找替换与书签操作完全指南
  • 做网站和app哪个难单页网站 jquery