原型模式详解
目录
原型模式简介
定义
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有实例来创建新的实例,而不是通过新建类的方式。原型模式允许一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。
核心思想
- 克隆创建:通过克隆现有对象来创建新对象
- 避免重复创建:避免重复创建相似对象的开销
- 动态配置:可以在运行时动态配置对象
- 简化创建过程:简化复杂对象的创建过程
模式结构
- Prototype(抽象原型类):声明克隆自身的接口
- ConcretePrototype(具体原型类):实现克隆自身的操作
- Client(客户端):使用原型实例克隆出新的实例
核心流程
原型模式流程图
基本实现流程
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);
}
@Override
public 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; }
@Override
public 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;
}
@Override
public 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);
}
@Override
public 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);
}
@Override
public 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;
}
@Override
public Prototype clone() {
return cache.computeIfAbsent(key, k -> prototype.clone());
}
}
Spring中的源码分析
Spring Bean的原型模式
// AbstractBeanFactory中的原型Bean处理
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <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;
// 尝试从缓存中获取单例Bean
Object 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 {
// 其他作用域的Bean
String 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 {
@Override
public void copyProperties(Object source, Object target) {
copyProperties(source, target, null, (String[]) null);
}
@Override
public 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<>();
}
@Override
public 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<>();
}
@Override
public 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<>();
}
@Override
public 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);
}
}
面试高频点
面试知识点思维导图
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;
}
@Override
public 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. 实际应用场景
问题:原型模式适用于哪些场景?
答案要点:
- 配置对象:数据库配置、系统配置等
- 文档模板:报告模板、信件模板等
- 游戏对象:角色、道具、场景等
- 缓存对象:需要频繁创建相似对象
- 复杂对象:创建成本较高的复杂对象
使用总结
原型模式的优势
- 性能优化:避免重复创建相似对象的开销
- 简化创建:简化复杂对象的创建过程
- 动态配置:可以在运行时动态配置对象
- 代码复用:通过克隆实现代码复用
原型模式的缺点
- 深克隆复杂:深克隆实现复杂,容易出错
- 内存开销:需要维护原型对象,占用内存
- 循环引用:深克隆时可能遇到循环引用问题
- 性能问题:深克隆可能影响性能
使用建议
- 简单对象:只用于创建简单对象,复杂对象考虑其他模式
- 深克隆:需要深克隆时,考虑使用序列化方式
- 线程安全:多线程环境下注意线程安全
- 性能考虑:权衡克隆成本和创建成本
最佳实践
- 实现Cloneable接口:正确实现Cloneable接口
- 深克隆实现:需要深克隆时,手动复制引用对象
- 异常处理:正确处理CloneNotSupportedException
- 文档注释:为克隆方法添加详细的文档注释
- 单元测试:为克隆功能编写单元测试
与其他模式的对比
- 与工厂模式:原型模式通过克隆创建,工厂模式通过新建创建
- 与建造者模式:原型模式克隆现有对象,建造者模式构建新对象
- 与单例模式:原型模式创建多个实例,单例模式创建唯一实例
原型模式是一种有用的创建型设计模式,特别适用于需要创建大量相似对象、配置对象克隆、模板对象克隆等场景。通过合理使用原型模式,可以大大提高系统的性能和灵活性。
8709

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



