原型模式是什么?
原型模式(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 setterspublic 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);}@Overridepublic Book clone() {return new Book(this);}}public class Person implements Prototype<Person> {private String firstName;private String lastName;// getters and setterspublic Person(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}private Person(Person person) {this(person.getFirstName(), person.getLastName());}@Overridepublic Person clone() {return new Person(this);}@Overridepublic String toString() {return firstName + " " + lastName;}}
即使还有继承关系,仍然可以通过拷贝构造方法来实现克隆方法。
public class EBook extends Book {private String format;// getter and setterpublic 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());}@Overridepublic EBook clone() {return new EBook(this);}}
案例源码
可在 GitHub 上查看上述案例的完整代码。
参考资料
以下是本文参考的资料:
