聊聊设计模式——原型模式
目录
1.原型模式定义
2.优点
3.缺点
4.原型模式结构说明
5.工作流程
6.示例
7.应用场景
8.本质
9.涉及的设计原则
10.与其他设计模式的关系
11.开源框架中的应用:
原型模式定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
优点:
-
性能提高:原型模式通常通过内存拷贝来创建新对象,这比通过构造函数创建对象要快,特别是当对象的创建过程涉及大量初始化或计算时。
-
简化对象创建:对于复杂的对象,特别是那些需要复杂参数或多个步骤的对象,原型模式可以大大简化对象的创建过程。它避免了复杂构造函数和初始化代码。
-
保持对象状态一致性:原型模式创建的新对象与原始对象的状态一致,这对需要确保新对象状态与原对象一致的情况非常重要。
-
灵活性:原型模式允许动态添加或删除对象的属性,因为对象的克隆是基于对象的实例,而不依赖于具体的类。
-
减少资源消耗:通过原型模式,可以避免重复创建相似对象,从而减少内存消耗。
缺点:
-
深浅拷贝问题:原型模式的默认实现通常是浅拷贝,这意味着只有对象的基本数据类型成员和引用类型成员的引用被复制,不会递归地复制引用类型的内容。如果需要深拷贝,需要自行实现。
-
需要实现克隆方法:每个需要使用原型模式的类都必须实现克隆方法,这可能需要一些额外的工作。如果对象的结构复杂,克隆方法的实现可能会变得复杂。
-
破坏封装性:在某些情况下,克隆方法可能需要访问对象的内部状态,这可能会破坏对象的封装性。
-
需要谨慎处理引用类型成员:如果对象包含引用类型成员,并且不正确地处理这些成员的克隆,可能导致对象状态的不一致性。
原型模式结构说明:
-
抽象原型(Prototype):定义了一个抽象接口,声明了可以克隆自己的方法。
-
具体原型(Concrete Prototype):实现抽象原型接口,实现了克隆自己的方法,通常包括一个克隆方法来创建对象的副本。
-
客户端(Client):使用原型对象的客户端代码,通常通过克隆来创建新的对象实例。
工作流程:
-
客户端通过原型对象的克隆方法请求新的对象实例。
-
具体原型对象执行克隆操作,返回一个新的对象副本。
?示例:
定义一个抽象接口Person,需要一个实现克隆自身的方法clone()。
// 抽象原型 —— 人类
public interface Person {
Person clone();
}
定义一个具体原型Man,重写clone()方法完成复制。
// 具体的原型 - 男人
public class Man implements Person{
private String sex = "男人";
private String name;
public Man(String name) {
this.name = name;
}
@Override
public Person clone() {
return new Man(this.name);
}
@Override
public String toString() {
return "Man{" +
"sex='" + sex + '\'' +
", name='" + name + '\'' +
'}';
}
}
客户端代码,通过clone()方法创建指定对象。
/*
原型模式的拷贝分为深拷贝和浅拷贝:
对象只有基本类型属性的是浅拷贝;
引用类型属性的是深拷贝,深拷贝中的引用需全部逐层拷贝完成才算成功。
不管哪种拷贝类型,改变克隆对象都不会影响实例原型的属性。
*/
public class Client {
public static void main(String[] args) {
Person person = new Man("小帅");
Person person1 = person.clone();
System.out.println(person == person1);
System.out.println(person);
System.out.println(person1);
}
}
?在java中,通过实现Cloneable接口覆盖Object类的clone方法也可以实现复制。
public class PrototypeJava implements Cloneable{
private String field;
public PrototypeJava(String field){
this.field = field;
}
// 克隆方法的真正实现
public Object clone(){
Object obj = null;
try{
obj = super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return obj;
}
@Override
public String toString() {
return "PrototypeJava{" +
"field='" + field + '\'' +
'}';
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
?需要注意的是:
-
默认情况下,通过
Cloneable
接口进行的克隆是浅拷贝,即只复制对象的引用,而不复制引用类型字段的内容。 -
如果需要进行深拷贝,需要在
clone
方法中手动复制引用类型字段的内容,确保所有对象都是独立的。 -
Cloneable
接口本身没有定义方法,因此没有强制要求实现类提供clone
方法。 -
对于可变对象,克隆后的对象和原始对象可能共享一些内部状态,因此需要谨慎处理。
-
clone
方法是一种原始的对象复制机制,通常在 Java 中更推荐使用其他方式来实现对象的复制,例如使用序列化和反序列化,或使用拷贝构造函数等。
应用场景:
-
当对象的创建成本较高,但需要多个相似对象时,可以使用原型模式节省资源。
-
当希望避免构造函数的复杂初始化逻辑,而是通过复制现有对象来创建新对象时,原型模式很有用。
-
当对象的类层次结构比较固定,但需要创建不同配置或状态的对象时,原型模式可以帮助快速创建变种对象。
本质:
????????原型模式的本质是复制已有对象,以创建新的对象实例,而不是从头开始构建。它通过克隆(拷贝)现有对象来创建新对象。
涉及的设计原则:
- 开闭原则(Open-Closed Principle):原型模式允许在不修改现有代码的情况下添加新类型的对象,符合开闭原则。
与其他设计模式的关系:
- 原型模式与工厂方法模式有一些相似之处,但工厂方法模式是用于创建不同类型的对象,而原型模式用于复制相似对象的实例。
开源框架中的应用:
在开源框架中,许多框架使用原型模式来创建对象的克隆,以提高性能和减少内存开销。例如,Spring框架中的BeanFactory
可以被视为原型模式的应用,它通过克隆已有的Bean定义来创建新的Bean实例。这减少了对象的初始化成本,提高了性能。同样,Hibernate中也使用原型模式来创建持久化对象的本。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!