Java设计模式之原型模式
基本介绍 (1)原型模式(Prototype 模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象 (2)原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节 (3)工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone() UML类图 说明: (1)Prototype:原型类,声明一个克隆自己的接口 (2)Concreteprototype:具体的原型类,实现一个克隆自己的操作 (3)Client:让一个原型对象克隆自己,从而创建一个新的对象 案例 原型模式解决克隆羊的问题
public class Sheep implements Cloneable {
private String name;
private int age;
private String color;
private String address = "蒙古羊" ;
public Sheep friend;
public Sheep ( String name, int age, String color) {
super ( ) ;
this . name = name;
this . age = age;
this . color = color;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public int getAge ( ) {
return age;
}
public void setAge ( int age) {
this . age = age;
}
public String getColor ( ) {
return color;
}
public void setColor ( String color) {
this . color = color;
}
@Override
public String toString ( ) {
return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]" ;
}
@Override
protected Object clone ( ) {
Sheep sheep = null;
try {
sheep = ( Sheep) super . clone ( ) ;
} catch ( Exception e) {
System. out. println ( e. getMessage ( ) ) ;
}
return sheep;
}
}
public class Client {
public static void main ( String[ ] args) {
System. out. println ( "原型模式完成对象的创建" ) ;
Sheep sheep = new Sheep ( "tom" , 1 , "白色" ) ;
sheep. friend = new Sheep ( "jack" , 2 , "黑色" ) ;
Sheep sheep2 = ( Sheep) sheep. clone ( ) ;
Sheep sheep3 = ( Sheep) sheep. clone ( ) ;
Sheep sheep4 = ( Sheep) sheep. clone ( ) ;
Sheep sheep5 = ( Sheep) sheep. clone ( ) ;
System. out. println ( "sheep2 =" + sheep2 + "sheep2.friend=" + sheep2. friend. hashCode ( ) ) ;
System. out. println ( "sheep3 =" + sheep3 + "sheep3.friend=" + sheep3. friend. hashCode ( ) ) ;
System. out. println ( "sheep4 =" + sheep4 + "sheep4.friend=" + sheep4. friend. hashCode ( ) ) ;
System. out. println ( "sheep5 =" + sheep5 + "sheep5.friend=" + sheep5. friend. hashCode ( ) ) ;
}
}
原型模式在Spring框架中源码分析 (1)Spring中原型bean的创建就是原型模式的应用。 (2)代码分析+Debug源码 浅拷贝和深拷贝 (1)浅拷贝 ① 数据类型是基本数据类型 的成员变量,浅拷贝会直接进行值传递 ,就是把属性值复制一份给新的对象。 ② 数据类型是引用类型 的成员变量,浅拷贝会进行引用传递 ,就是把成员变量的引用地址复制一份给新的对象。这种情况下,一个对象中的成员变量发生修改,另外一个对象也会修改。 ③ 浅拷贝是使用默认的clone方法来实现的,像前面的克隆羊sheep = (Sheep) super.clone(); (2)深拷贝 ① 重写clone方法实现深拷贝 ② 使用序列化实现深拷贝(推荐) ③ 代码实现
public class DeepCloneableTarget implements Serializable , Cloneable {
private static final long serialVersionUID = 1 L;
private String cloneName;
private String cloneClass;
public DeepCloneableTarget ( String cloneName, String cloneClass) {
this . cloneName = cloneName;
this . cloneClass = cloneClass;
}
@Override
protected Object clone ( ) throws CloneNotSupportedException {
return super . clone ( ) ;
}
}
public class DeepProtoType implements Serializable , Cloneable{
public String name;
public DeepCloneableTarget deepCloneableTarget;
public DeepProtoType ( ) {
super ( ) ;
}
@Override
protected Object clone ( ) throws CloneNotSupportedException {
Object deep = null;
deep = super . clone ( ) ;
DeepProtoType deepProtoType = ( DeepProtoType) deep;
deepProtoType. deepCloneableTarget = ( DeepCloneableTarget) deepCloneableTarget. clone ( ) ;
return deepProtoType;
}
public Object 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) ;
DeepProtoType copyObj = ( DeepProtoType) ois. readObject ( ) ;
return copyObj;
} catch ( Exception e) {
e. printStackTrace ( ) ;
return null;
} finally {
try {
bos. close ( ) ;
oos. close ( ) ;
bis. close ( ) ;
ois. close ( ) ;
} catch ( Exception e2) {
System. out. println ( e2. getMessage ( ) ) ;
}
}
}
}
public class Client {
public static void main ( String[ ] args) throws Exception {
DeepProtoType p = new DeepProtoType ( ) ;
p. name = "宋江" ;
p. deepCloneableTarget = new DeepCloneableTarget ( "大牛" , "小牛" ) ;
DeepProtoType p2 = ( DeepProtoType) p. deepClone ( ) ;
System. out. println ( "p.name=" + p. name + "p.deepCloneableTarget=" + p. deepCloneableTarget. hashCode ( ) ) ;
System. out. println ( "p2.name=" + p. name + "p2.deepCloneableTarget=" + p2. deepCloneableTarget. hashCode ( ) ) ;
}
}
原型模式的注意事项和细节 (1)创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率 (2)不用重新初始化对象,而是动态地获得对象运行时的状态 (3)如果原始对象发生变化(增加或者减少属性),其它克隆对象的也会发生相应的变化,无需修改代码 (4)缺点:需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源代码,违背了 ocp 原则,