目录
一、前言
二、原型模式定义
三、原型模式的实现方式
1、浅拷贝(Shallow Copy)
2、深拷贝(Deep Copy)
2.1、重写clone方法来实现深拷贝
2.2、通过对象序列化实现深拷贝
2.3、方式 1 和方式 2 对比
四、原型模式应用场景
1、对象创建成本高昂
2、动态配置
3、保护对象状态
五、原型模式优点
1、简化对象创建
2、减少资源消耗
3、保护对象
六、注意事项
1、深拷贝的复杂性
2、克隆方法的实现
七、代码示例
八、总结
一、前言
设计模式作为软件开发的指导原则,其中原型模式是一种独特而有价值的模式。本文将深入探究原型模式在设计模式中的价值,解析其创新思想和应用场景,带您领略原型模式的精髓。
二、原型模式定义
原型模式是一种创建型设计模式,它允许对象通过复制自身来创建新的对象,而无需使用构造函数。原型模式通过将对象的复制与客户端代码解耦,提供了更灵活和可扩展的对象创建方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。
三、原型模式的实现方式
1、浅拷贝(Shallow Copy)
浅拷贝创建一个新对象,将原始对象的属性值复制到新对象中。如果属性值是基本类型,复制的是值本身;如果属性是引用类型,复制的是引用。因此,两个对象的引用类型属性仍然指向同一内存地址。
2、深拷贝(Deep Copy)
深拷贝创建一个全新的对象,同时递归地复制所有嵌套对象及其属性。这样,新对象和原始对象完全独立,不会共享任何引用类型属性。
2.1、重写clone方法来实现深拷贝
public class DeepClonableTarget implements Serializable, Cloneable {
private String cloneName;
private String cloneClass;
public DeepClonableTarget(String cloneName, String cloneClass) {
this.cloneName = cloneName;
this.cloneClass = cloneClass;
}
public String getCloneName() {
return cloneName;
}
public void setCloneName(String cloneName) {
this.cloneName = cloneName;
}
public String getCloneClass() {
return cloneClass;
}
public void setCloneClass(String cloneClass) {
this.cloneClass = cloneClass;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class DeepPrototype implements Serializable, Cloneable {
private String name;
private DeepClonableTarget deepClonableTarget;
public DeepPrototype() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public DeepClonableTarget getDeepClonableTarget() {
return deepClonableTarget;
}
public void setDeepClonableTarget(DeepClonableTarget deepClonableTarget) {
this.deepClonableTarget = deepClonableTarget;
}
@Override
protected Object clone() throws CloneNotSupportedException {
//基本数据类型拷贝
Object object = super.clone();
//引用类型拷贝
DeepPrototype deepPrototype = (DeepPrototype) object;
deepPrototype.deepClonableTarget = (DeepClonableTarget) deepClonableTarget.clone();
return object;
}
}
public class DeepTest {
public static void main(String[] args) throws CloneNotSupportedException {
DeepPrototype prototype = new DeepPrototype();
prototype.setName("宋江");
prototype.setDeepClonableTarget(new DeepClonableTarget("及时雨", "及时雨的类"));
DeepPrototype clone1 = (DeepPrototype) prototype.clone();
DeepPrototype clone2 = (DeepPrototype) prototype.clone();
DeepPrototype clone3 = (DeepPrototype) prototype.clone();
DeepPrototype clone4 = (DeepPrototype) prototype.clone();
DeepPrototype clone5 = (DeepPrototype) prototype.clone();
System.out.println(prototype.getName() + ", " + prototype.getDeepClonableTarget().hashCode()); // 宋江, 1554874502
System.out.println(clone1.getName() + ", " + clone1.getDeepClonableTarget().hashCode()); // 宋江, 1846274136
System.out.println(clone2.getName() + ", " + clone2.getDeepClonableTarget().hashCode()); // 宋江, 1639705018
System.out.println(clone3.getName() + ", " + clone3.getDeepClonableTarget().hashCode()); // 宋江, 1627674070
System.out.println(clone4.getName() + ", " + clone4.getDeepClonableTarget().hashCode()); // 宋江, 1360875712
System.out.println(clone5.getName() + ", " + clone5.getDeepClonableTarget().hashCode()); // 宋江, 1625635731
}
}
2.2、通过对象序列化实现深拷贝
public class DeepClonableTarget implements Serializable, Cloneable {
private String cloneName;
private String cloneClass;
public DeepClonableTarget(String cloneName, String cloneClass) {
this.cloneName = cloneName;
this.cloneClass = cloneClass;
}
public String getCloneName() {
return cloneName;
}
public void setCloneName(String cloneName) {
this.cloneName = cloneName;
}
public String getCloneClass() {
return cloneClass;
}
public void setCloneClass(String cloneClass) {
this.cloneClass = cloneClass;
}
}
public class DeepPrototype implements Serializable, Cloneable {
private String name;
private DeepClonableTarget deepClonableTarget;
public DeepPrototype() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public DeepClonableTarget getDeepClonableTarget() {
return deepClonableTarget;
}
public void setDeepClonableTarget(DeepClonableTarget deepClonableTarget) {
this.deepClonableTarget = deepClonableTarget;
}
public DeepPrototype deepClone() {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return (DeepPrototype) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (ois != null) {
ois.close();
}
if (bis != null) {
bis.close();
}
if (oos != null) {
oos.close();
}
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class DeepTest {
public static void main(String[] args) throws CloneNotSupportedException {
DeepPrototype prototype = new DeepPrototype();
prototype.setName("宋江");
prototype.setDeepClonableTarget(new DeepClonableTarget("及时雨", "及时雨的类"));
DeepPrototype clone1 = prototy服务器托管网pe.deepClone();
DeepPrototype clone2 = prototype.deepClone();
DeepPrototype clone3 = prototype.deepClone();
DeepPrototype clone4 = prototype.deepClone();
DeepPrototype clone5 = prototype.deepClone();
System.out.println(prototype.getName() + ", " + prototype.getDeepClonableTarget().hashCode()); // 宋江, 644117698
System.out.println(clone1.getName() + ", " + clone1.getDeepClonableTarget().hashCode()); // 宋江, 317574433
System.out.println(clone2.getName() + ", " + clone2.getDeepClonableTarget().hashCode()); // 宋江, 885284298
System.out.p服务器托管网rintln(clone3.getName() + ", " + clone3.getDeepClonableTarget().hashCode()); // 宋江, 1389133897
System.out.println(clone4.getName() + ", " + clone4.getDeepClonableTarget().hashCode()); // 宋江, 1534030866
System.out.println(clone5.getName() + ", " + clone5.getDeepClonableTarget().hashCode()); // 宋江, 664223387
}
}
2.3、方式 1 和方式 2 对比
● 在对象引用类型的成员属性较少时,方式 1 简单;在对象引用类型的成员属性较多时,方式 2 简单
● 在对象引用类型的成员属性经常发生变化时,方式 1 需要同步修改,方式 2 不用修改
● 推荐使用方式 2:耦合性低、可维护性强、扩展性高
四、原型模式应用场景
1、对象创建成本高昂
如果创建对象的过程很复杂或耗费资源,原型模式可以提高性能,通过复制已有对象来创建新对象。
2、动态配置
当需要根据运行时的配置创建对象时,原型模式可以用于在不修改代码的情况下创建新对象。
3、保护对象状态
如果对象的某些属性需要保护,不希望在外部进行修改,可以使用原型模式来创建新对象。
五、原型模式优点
1、简化对象创建
原型模式提供了一种简单的方式来复制对象,避免了重复的初始化过程。
2、减少资源消耗
原型模式避免了重复创建大量相似对象,减少了资源的消耗
3、保护对象
原型模式可以用于保护对象状态,防止外部修改敏感属性。
六、注意事项
1、深拷贝的复杂性
深拷贝可能会引入循环引用和递归复制的问题,需要谨慎处理。
2、克隆方法的实现
对象的克隆方法需要正确地复制所有属性,包括引用类型属性。
七、代码示例
abstract class Shape implements Cloneable {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public abstract void draw();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Circle extends Shape {
public Circle() {
setType("Circle");
}
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle extends Shape {
public Rectangle() {
setType("Rectangle");
}
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
八、总结
原型模式是一种有力的设计模式,它通过对象的复制和创建来提供更灵活和可扩展的方式。无论是浅拷贝还是深拷贝,原型模式都可以在需要复制对象的情况下发挥重要作用。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
有一个项目用来负责调度集群中的”cron任务”,比如一个application中可以配置N个定时任务,这些任务信息最终注册到zookeeper上,并开发了一系列代码用于维护这些任务的”活性”;当applicaton中一个server故障,那么这个serve…