原型模式 (Prototype Pattern) 是首先创建一个原型对象, 再通过复制这个原型对象来创建更多同类型的对象. 这种类型的设计模式属于创建型模式, 它提供了一种创建对象的最佳方式.
这种模式是实现了一个原型接口, 该接口用于创建当前对象的克隆. 当直接创建对象的代价比较大时, 则采用这种模式. 例如, 一个对象需要在一个高代价的数据库操作之后被创建. 我们可以缓存该对象, 在下一个请求时返回它的克隆, 在需要的时候更新数据库, 以此来减少数据库调用.
在原型模式结构图中包含如下几个角色:
1.Prototype(抽象原型类): 它是声明克隆方法的接口, 是所有具体原型类的公共父类, 可以是抽象类也可以是接口, 甚至还可以是具体实现类.
2.ConcretePrototype(具体原型类): 它实现在抽象原型类中声明的克隆方法, 在克隆方法中返回自己的一个克隆对象.
3.Client(客户类): 让一个原型对象克隆自身创建一个新的对象, 在客户类中只需要直接实例化或通过工厂方法等方式创建一个原型对象, 再通过调用该对象的克隆方法即可得到多个相同的对象. 由于客户类针对抽象原型类 Prototype 编程, 因此用户可以根据需要选择具体原型类, 系统具有较好的可扩展性, 增加或更换具体原型类都很方便.
原型模式的核心在于如何实现克隆方法, 下面将介绍两种在 Java 语言中常用的克隆实现方法:
1. 通用实现方法. 通用的克隆实现方法是在具体原型类的克隆方法中实例化一个与自身类型相同的对象并将其返回, 并将相关的参数传入新创建的对象中, 保证它们的成员属性相同. 示意代码如下所示:
- class ConcretePrototype implements Prototype{
- private String attr; // 成员属性
- public void setAttr(String attr)
- {
- this.attr = attr;
- }public String getAttr()
- {
- return this.attr;
- }
- public Prototype clone() // 克隆方法
- {
- Prototype prototype = new ConcretePrototype(); // 创建新对象
- prototype.setAttr(this.attr);
- return prototype;
- }
- }
Java 语言提供的 clone()方法. 学过 Java 语言的人都知道, 所有的 Java 类都继承自 java.lang.Object. 事实上, Object 类提供一个 clone()方法, 可以将一个 Java 对象复制一份. 因此在 Java 中可以直接使用 Object 提供的 clone()方法来实现对象的克隆, Java 语言中的原型模式实现很简单.
需要注意的是能够实现克隆的 Java 类必须实现一个标识接口 Cloneable, 表示这个 Java 类支持被复制. 如果一个类没有实现这个接口但是调用了 clone()方法, Java 编译器将抛出一个 CloneNotSupportedException 异常. 如下代码所示:
- class ConcretePrototype implements Cloneable
- {
- ......public Prototype clone(){
- Object object = null;try {
- object = super.clone();
- } catch (CloneNotSupportedException exception)
- {
- System.err.println("Not support cloneable");
- }
- return (Prototype )object;
- }......
- }
在客户端创建原型对象和克隆对象也很简单, 如下代码所示:
- Prototype obj1 = new ConcretePrototype();
- Prototype obj2 = obj1.clone();
一般而言, Java 语言中的 clone()方法满足:
1)对任何对象 x, 都有 x.clone() != x, 即克隆对象与原型对象不是同一个对象;
2)对任何对象 x, 都有 x.clone().getClass() == x.getClass(), 即克隆对象与原型对象的类型一样;
3)如果对象 x 的 equals()方法定义恰当, 那么 x.clone().equals(x)应该成立. 为了获取对象的一份拷贝, 我们可以直接利用 Object 类的 clone()方法, 具体步骤如下:
a. 在派生类中覆盖基类的 clone()方法, 并声明为 public;
b. 在派生类的 clone()方法中, 调用 super.clone();
c. 派生类需实现 Cloneable 接口.
此时, Object 类相当于抽象原型类, 所有实现了 Cloneable 接口的类相当于具体原型类.
来源: http://www.bubuko.com/infodetail-2866211.html