设计模式中的原型模式(Prototype Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式,即直接复制现有的对象,而不是通过实例化类来创建新对象。这种模式在需要快速生成大量相似对象时非常有用,尤其是当对象的创建成本较高(如资源消耗大、初始化时间长等)时。下面是对原型模式的详细介绍:
原型模式是指通过原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。在原型模式中,客户端可以直接从原型对象通过克隆来创建新的对象,而无需了解对象创建的细节。
原型模式的工作原理是通过将一个原型对象传给需要创建新对象的客户端,客户端通过调用原型对象的克隆方法(通常是clone()
方法)来复制该原型对象,从而得到一个新的对象实例。这个新对象与原型对象在内容上是相同的,但它们在内存中拥有不同的地址,即它们是两个独立的对象。
在Java中,实现原型模式通常涉及到实现Cloneable
接口并重写clone()
方法。不过,从Java 9开始,引入了java.lang.Cloneable
的一个默认方法clone()
的规范实现(尽管它是受保护的),但实际上Object
类中的clone()
方法是一个受保护的方法,它默认是抛出CloneNotSupportedException
的,除非类实现了Cloneable
接口。因此,即使Java 9及以后版本有了一些改进,但实现原型模式时,仍然需要显式地实现Cloneable
接口并重写clone()
方法。
下面是一个简单的Java原型模式示例:
// 抽象原型类 abstract class Prototype implements Cloneable { private String id; // 构造方法 public Prototype(String id) { this.id = id; } // 抽象克隆方法 public abstract Prototype clone(); // 通用方法 public void show() { System.out.println("ID: " + id); } } // 具体原型类 class ConcretePrototype extends Prototype { // 构造方法 public ConcretePrototype(String id) { super(id); } // 实现克隆方法 @Override public ConcretePrototype clone() { try { return (ConcretePrototype) super.clone(); } catch (CloneNotSupportedException e) { // 这里不应该发生,因为我们实现了Cloneable接口 throw new InternalError(e); } } } // 客户端类 public class Client { public static void main(String[] args) { // 创建一个原型对象 Prototype original = new ConcretePrototype("123"); // 克隆原型对象 Prototype cloned = original.clone(); // 检查是否创建了新的对象实例 System.out.println("Original: " + original.hashCode()); System.out.println("Cloned: " + cloned.hashCode()); // 调用方法以验证克隆对象的行为 original.show(); cloned.show(); } }
在这个例子中,Prototype
是一个抽象原型类,它实现了Cloneable
接口并定义了一个抽象的clone()
方法。注意,由于clone()
方法在Object
类中是受保护的,因此我们不能直接在Prototype
类中实现它(除非我们将其声明为受保护的或包私有的,但这会限制其使用)。然而,在这个示例中,我们让clone()
方法在Prototype
类中保持抽象,以便在子类中实现。
ConcretePrototype
是具体原型类,它实现了Prototype
接口并重写了clone()
方法。在clone()
方法中,我们调用了super.clone()
来创建当前对象的浅拷贝,并将其强制转换为ConcretePrototype
类型。然后,我们处理了可能的CloneNotSupportedException
,但在这个例子中,由于我们实现了Cloneable
接口,所以不会抛出此异常。
最后,在Client
类中,我们创建了一个ConcretePrototype
对象,并使用其clone()
方法创建了一个克隆对象。然后,我们验证了这两个对象是否真的是不同的实例(通过打印它们的哈希码),并调用了show()
方法来验证克隆对象的行为是否与原始对象相同。读者可以试试,应该是不相同的。
原型模式是一种非常实用的设计模式,它通过拷贝现有对象来创建新对象,简化了对象的创建过程,并提高了性能。然而,在使用时需要注意深拷贝和浅拷贝的区别,以及实现克隆方法可能带来的复杂性。如果生产环境使用,一定要注意深浅拷贝的影响,要慎重。