设计模式:原型模式(Prototype)

设计模式:原型模式(Prototype)

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

举个例子:

1 原型(实际上是implements了Cloneable接口,进而重写clone()方法)

public class ProtoType implements Cloneable
{
private String name;

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

public String getName()
{
return name;
}

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

2 测试代码

public class MainTest
{
public static void main(String[] args)
{
ProtoType pt1 = new ProtoType();
pt1.setName("protoType_1");
ProtoType pt2 = pt1.clone();
System.out.println(pt1 == pt2);
System.out.println(pt1.getClass() == pt2.getClass());
pt2.setName("protoType_2");
System.out.println(pt1.getName()+" "+pt2.getName());
}
}

输出:

false
true
protoType_1 protoType_2

克隆还分为浅克隆和深克隆,细节这里就不赘述了。在《Effective Java》中作者提出了“谨慎地覆盖clone”,文中提出了Cloneable的许多问题,建议使用拷贝构造器的方法来替换Cloneable.

优缺点

优点:

  1. 如果创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
  2. 可以使用深克隆保持对象的状态。
  3. 原型模式提供了简化的创建结构。

缺点:

  1. 在实现深克隆的时候可能需要比较复杂的代码。
  2. 需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

适用场景

  1. 如果创建新对象成本较大,我们可以利用已有的对象进行复制来获得。
  2. 如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
  3. 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

Jdk中的原型模式
java.lang.Object#clone()
java.lang.Cloneable

参考资料:

  1. 23种设计模式
  2. 《Effective Java(Second Edition)》Joshua Bloch.
  3. 细数JDK里的设计模式

欢迎支持笔者的作品《深入理解Kafka: 核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客(ID: hiddenkafka)。
本文作者: 朱小厮

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×