Java设计模式之原型模式(7)
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
原型的类关系图: 时序图:代码实现:
package study_02.designpattern.prototype;public interface PrototypeCapable extends Cloneable{ public PrototypeCapable clone() throws CloneNotSupportedException;}
package study_02.designpattern.prototype;public class Movie implements PrototypeCapable{ private String name = null; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Movie clone() throws CloneNotSupportedException { System.out.println("Cloning Movie object.."); return (Movie) super.clone(); } @Override public String toString() { return "Movie"; }}
package study_02.designpattern.prototype;public class Album implements PrototypeCapable{ private String name = null; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Album clone() throws CloneNotSupportedException { System.out.println("Cloning Album object.."); return (Album) super.clone(); } @Override public String toString() { return "Album"; }}
package study_02.designpattern.prototype;public class Show implements PrototypeCapable{ private String name = null; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Show clone() throws CloneNotSupportedException { System.out.println("Cloning Show object.."); return (Show) super.clone(); } @Override public String toString() { return "Show"; }}
package study_02.designpattern.prototype;public class PrototypeFactory{ public static class ModelType { public static final String MOVIE = "movie"; public static final String ALBUM = "album"; public static final String SHOW = "show"; } private static java.util.Map<String , PrototypeCapable> prototypes = new java.util.HashMap<String , PrototypeCapable>(); static { prototypes.put(ModelType.MOVIE, new Movie()); prototypes.put(ModelType.ALBUM, new Album()); prototypes.put(ModelType.SHOW, new Show()); } public static PrototypeCapable getInstance(final String s) throws CloneNotSupportedException { return ((PrototypeCapable) prototypes.get(s)).clone(); }}
package study_02.designpattern.prototype;import study_02.designpattern.prototype.PrototypeFactory.ModelType;public class TestPrototypePattern{ public static void main(String[] args) { try { String moviePrototype = PrototypeFactory.getInstance(ModelType.MOVIE).toString(); System.out.println(moviePrototype); String albumPrototype = PrototypeFactory.getInstance(ModelType.ALBUM).toString(); System.out.println(albumPrototype); String showPrototype = PrototypeFactory.getInstance(ModelType.SHOW).toString(); System.out.println(showPrototype); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }}
输出结果:
Cloning Movie object..
Movie
Cloning Album object..
Album
Cloning Show object..
Show
克隆必须满足的条件:
a.对任何的对象x,都有:x.clone()!=x,即克隆对象与原对象不是同一个对象。
b.对任何的对象x,都有:x.clone().getClass()==x.get getClass(),即克隆对象与原对象的类型是一样的。
c.如果对象x的equals()方法定义恰当的话,那么x.clone().equals(x)应当是成立的。
在java中实现clone()应该满足这三个条件。
浅复制:复制了值类型对象,对于引用类型对象,只复制了引用,它指向原来引用的对象。Java中clone为浅复制。
深复制:对值类型和引用类型的对象都生成一份新的拷贝. Java中可以通过串行化来进行深复制,前提是对象以及对象内部所引用的对象都是可串行化的,否则需要考虑将那些不可串行化的对象可否设为transient,排除在复制过程之外。
被复制对象的任何变量都含有和原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
参考资料:
http://howtodoinjava.com/2013/01/04/prototype-design-pattern-in-java/
http://www.cnblogs.com/java-my-life/archive/2012/04/11/2439387.html
http://www.tutorialspoint.com/design_pattern/prototype_pattern.htm
http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/