设计模式之原型模式

原型模式

原型模式

原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,属于创建型模式。

原型模式的核心在于拷贝原型对象。以系统中已存在的一个对象为原型,直接基于内存二进制流进行拷贝,无需再经历耗时的对象初始化过程(不调用构造函数),性能提升许多。当对象的构建过程比较耗时时,可以利用当前系统中已存在的对象作为原型,对其进行克隆(一般是基于二进制流的复制),躲避初始化过程,使得新对象的创建时间大大减少。

通用写法

先创建原型Prototype接口

1
2
3
4
public interface IPrototype<T>
{
T clone();
}

创建需要克隆的对象PrototypeClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class PrototypeClass implements IPrototype<PrototypeClass>
{
private String name;
private int age;

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public int getAge()
{
return age;
}

public void setAge(int age)
{
this.age = age;
}

@Override
public PrototypeClass clone()
{
PrototypeClass user = new PrototypeClass();
user.setName(name);
user.setAge(age);
return user;
}
}

浅克隆

原型模式就是克隆对象,实际运用中我们可以使用JDK自带的接口Cloneable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class PrototypeClass implements Cloneable
{
private String name;
private int age;

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public int getAge()
{
return age;
}

public void setAge(int age)
{
this.age = age;
}

@Override
public PrototypeClass clone()
{
try
{
return (PrototypeClass) super.clone();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
return null;
}
}

@Override
public String toString()
{
return "PrototypeClass{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}

调用父类的clone方法,JDK会自动帮我们克隆好,但这个是浅克隆,只会拷贝对象中的基本数据类型的数据(比如,int、long),以及引用对象(SearchWord)的内存地址,不会递归地拷贝引用对象本身。

深克隆

可以用序列化的方式实现深克隆,先将对象序列化,然后再反序列化成新的对象。

1
2
3
4
5
6
7
8
9
10
11
public Object deepCopy() throws Exception
{
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);

ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);

return oi.readObject();
}

也可以使用json序列化方式

原型模式优缺点

优点:
1、性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
2、可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。

缺点:
1、需要为每一个类配置一个克隆方法。
2、克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
3、在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深拷贝、浅拷贝需要运用得当。

打赏

请我喝杯咖啡吧~

支付宝
微信