原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。
原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。
实现
public class WhiteSoldier {
public synchronized WhiteSoldier create() throws CloneNotSupportedException {
try {
return (WhiteSoldier)this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
public void war(){
System.out.println("打仗去了。。");
}
}
WhiteSoldier whiteSoldier = new WhiteSoldier();
WhiteSoldier whiteSoldier1 = whiteSoldier.create();
WhiteSoldier whiteSoldier2 = whiteSoldier.create();
whiteSoldier1.war();
whiteSoldier2.war();
带有管理器的实现
public class Manage {
private HashMap<String,Product> showcase = new HashMap<>();
public void register(String name,Product proto){
showcase.put(name,proto);
}
public Product create(String name){
Product product = showcase.get(name);
return product.createClone();
}
}
public abstract class Product implements Cloneable {
public abstract void user(String s);
public Product createClone(){
Product p = null;
try {
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
};
}
public class MessageBox extends Product {
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
public void user(String s) {
int len = s.getBytes().length;
for (int i = 0 ; i < len + 4;i++){
System.out.print(decochar);
}
System.out.println();
System.out.println(decochar+s+decochar);
for (int i = 0 ; i < len + 4;i++){
System.out.print(decochar);
}
System.out.println();
}
}
public class UnderlinePen extends Product {
private char ulchar;
public UnderlinePen(char ulchar) {
this.ulchar = ulchar;
}
@Override
public void user(String s) {
int len = s.getBytes().length;
System.out.println("\""+s+"\"");
System.out.print(" ");
for (int i = 0 ; i < len ; i ++){
System.out.print(ulchar);
}
System.out.println();
}
}
//准备
Manage manage = new Manage();
UnderlinePen underlinePen = new UnderlinePen('~');
MessageBox messageBox1 = new MessageBox('*');
MessageBox messageBox2 = new MessageBox('/');
manage.register("strong message",underlinePen);
manage.register("warning box",messageBox1);
manage.register("slash box",messageBox2);
// //生成
Product p1 = manage.create("strong message");
p1.user("hello,world.");
Product p2 = manage.create("warning box");
p2.user("hello,world.");
Product p3 = manage.create("slash box");
p3.user("hello,world.");
Cloneable接口
继承了该接口表示,当前类可以使用clone()方法。只是一个标志, clone()方法被定义在Object类中。未继承该接口的对象使用clone方法会抛出CloneNotSupportedException异常。
深克隆和浅克隆
java的clone方法是浅克隆,只复制了原型对象的值,包括基本类型和引用地址。clone后,多个被复制出来的对象内部的对象都是指向的同一个。
而深克隆则是被复制出来的对象内部的对象也是新的对象。
详细请参照这篇文章的克隆相关的图解:
https://blog.csdn.net/hguisu/article/details/7518947