设计模式系列
文章目录
前言
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
一、原型模式是什么?
把对象拷贝一份,产生一个新的对象,和原有对象一样。这种不通过new 关键字来产生一个对象,而是通过对象拷贝来实现的模式就叫做原型模式
二、使用步骤
1.实现cloneable接口对象的拷贝需要实现cloneable接口。
package java.lang;
/**
* A class implements the <code>Cloneable</code> interface to
* indicate to the {@link java.lang.Object#clone()} method that it
* is legal for that method to make a
* field-for-field copy of instances of that class.
* <p>
* Invoking Object's clone method on an instance that does not implement the
* <code>Cloneable</code> interface results in the exception
* <code>CloneNotSupportedException</code> being thrown.
* <p>
* By convention, classes that implement this interface should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.
* <p>
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
*
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}
2.简单示例
代码如下(示例):
/**
* 简单的clone
*/
public class SimpleClone implements Cloneable{
//属性问题
private String props;
public String getProps() {
return props;
}
public void setProps(String props) {
this.props = props;
}
/**
* 克隆方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected SimpleClone clone() {
SimpleClone simpleClone = null;
try {
simpleClone = (SimpleClone)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return simpleClone;
}
}
测试:
public class Client {
public static void main(String[] args) {
SimpleClone simpleClone = new SimpleClone();
System.out.println("原始对象"+simpleClone);
SimpleClone clone = simpleClone.clone();
System.out.println("原始对象"+simpleClone);
}
}
浅拷贝
Object 类提供的方法clone 只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝
浅拷贝:
/**
* 浅拷贝
*/
public class ShallowClone implements Cloneable{
//定义一个私有变量
private ArrayList<String> props = new ArrayList<String>();
public ArrayList<String> getProps() {
return props;
}
public void setProps(String prop) {
this.props.add(prop);
}
/**
* 克隆方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected ShallowClone clone() {
ShallowClone shallowClone = null;
try {
shallowClone = (ShallowClone)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return shallowClone;
}
}
client:
public class ShallowClient {
public static void main(String[] args) {
ShallowClone shallowClone = new ShallowClone();
shallowClone.setProps("浅拷贝前的对象属性值");
ShallowClone clone = shallowClone.clone();
clone.setProps("浅拷贝后的对象属性值");
System.out.println(shallowClone.getProps());
}
}
深拷贝:
/**
* 深拷贝
*/
public class DeepClone implements Cloneable {
//定义一个私有变量
private ArrayList<String> props = new ArrayList<String>();
public ArrayList<String> getProps() {
return props;
}
public void setProps(String prop) {
this.props.add(prop);
}
/**
* 克隆方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected DeepClone clone() {
DeepClone deepClone = null;
try {
deepClone = (DeepClone)super.clone();
//引用对象拷贝
deepClone.props = (ArrayList<String>)this.props.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return deepClone;
}
}
public class DeepClient {
public static void main(String[] args) {
DeepClone deepClone = new DeepClone();
deepClone.setProps("浅拷贝前的对象属性值");
DeepClone clone = deepClone.clone();
clone.setProps("浅拷贝后的对象属性值");
System.out.println(deepClone.getProps());
}
}
总结
一是类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等;二是通过new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式;三是一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者