一、基本概念
- 定义
**原型模式(Prototype Pattern)**是一种对象创建型模式,一种基于现有对象模板,通过克隆方式创建对象的模式。
-
模式结构
-
ProtoType(抽象原型类):定义具有克隆自己的方法的接口,是具体原型类的公共父类,接口或抽象类。
-
ConcretePrototype(具体原型类):实现具体的克隆方法,在方法中返回自己的一个克隆对象。
-
Client(客户类):让一个原型克隆自身,从而创建一个新的对象。
二、模式分析
Object类中提供能clone()方法,可以直接使用clone()方法来克隆对象,但是实现克隆的Java类必须实现一个Cloneable接口,表示该类是支持复制的,否则会抛出CloneNotSupportedException异常。
值得注意的是,使用clone方法创建的新对象的构造函数是不会被执行的,也就是说会绕过任何构造函数(有参和无参),因为clone方法的原理是从堆内存中以二进制流的方式进行拷贝,直接分配一块新内存。
比如下面的例子,具体原型类(蓝色类)实现/继承 抽象原型类(接口),再通过Object类中的clone()方法复制一份蓝色对象。
package com.color;
public class Blue implements MyColor {
public Object clone(){
Blue b = null;
try {
b = (Blue)super.clone();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return b;
}
public void display(){
System.out.println("This is Blue!");
}
}
三、浅克隆与深克隆
举一个简单的例子,孙悟空能根据自己的猴毛复制很多个孙悟空。当一个孙悟空在抓头发的时候,所有的对于孙悟空对象的引用都指向原始对象,并且同时在抓头发,这就是浅克隆。反之复制了属性,新复制的属性指向新的孙悟空(进行重写原有方法),从而表现有不同的动作,则为深克隆。
一封邮件简化为有名字、等级等成员属性和下载附件的方法,复制的时候没有包含了引用对象的下载附件的方法就为浅克隆,反之就为深克隆。
浅克隆
浅克隆中,被复制对象的所有普通成员变量都具有原来对象的相同的值,而所有对其他的引用都仍然指向原来的对象。
即当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而应用类型的成员变量并没有复制。
代码示例
-
类图
-
Attachment附件类
package com.email;
public class Attachment {
public void download(){
System.out.println("下载附件!");
}
}
- Email邮件类(具体原型类)
package work.email;
public class Email implements Cloneable{
private String emailTitle;
private int emailLevel;
public String getEmailTitle() {
return emailTitle;
}
public void setEmailTitle(String emailTitle) {
this.emailTitle = emailTitle;
}
public int getEmailLevel() {