原型模式是什么?
原型模式(Prototype Pattern)是一种创建型的设计模式。根据 GoF 对原型模式的定义:
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
它的意思是使用原型的实例指定要创建对象的种类,并通过拷贝此原型创建新的对象。原型模式就是对象的拷贝,关于 Java 语言的对象拷贝,可参考 https://www.yuque.com/huey/java/shallow-copy-and-deep-copy。
原型模式为所有支持克隆的对象声明了一个通用的接口,该接口让我们能够克隆对象,但把复制过程委派给被克隆的实际对象。
UML 类图
用 UML 类图来描述原型模式的结构,在模式中各个角色之间的关系:
根据上图,总结了模式中各个角色的职责以及它们之间的关系:
原型是声明了克隆方法的接口,并且在大多数情况下,它也只声明这个方法。
具体原型会实现克隆方法。
客户端可以复制实现了原型接口的任何对象。
案例
让我们通过一个案例来帮助我们进一步理解原型模式。首先是原型接口的声明,它很简单,只有一个 clone 方法。
public interface Prototype<T> {
public T clone();
}
模型以图书为例,一本书有书名、作者等属性,其中作者以 Person 类表示,它包含了姓和名两个属性。它们都基于私有的拷贝构造方法实现了克隆方法。
public class Book implements Prototype<Book> {
private String name;
private Person author;
// getters and setters
public Book(String name, Person author) {
this.name = name;
this.author = author;
}
private Book(Book book) {
this(book.getName(), book.getEdition(), book.getAuthor() != null ? book.getAuthor().clone() : null);
}
@Override
public Book clone() {
return new Book(this);
}
}
public class Person implements Prototype<Person> {
private String firstName;
private String lastName;
// getters and setters
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
private Person(Person person) {
this(person.getFirstName(), person.getLastName());
}
@Override
public Person clone() {
return new Person(this);
}
@Override
public String toString() {
return firstName + " " + lastName;
}
}
即使还有继承关系,仍然可以通过拷贝构造方法来实现克隆方法。
public class EBook extends Book {
private String format;
// getter and setter
public EBook(String name, Person author, String format) {
super(name, author);
this.format = format;
}
private EBook(EBook eBook) {
this(eBook.getName(), eBook.getAuthor() != null ? eBook.getAuthor().clone() : null, eBook.getFormat());
}
@Override
public EBook clone() {
return new EBook(this);
}
}
案例源码
可在 GitHub 上查看上述案例的完整代码。
参考资料
以下是本文参考的资料: