ProtoType的英文意思是:原型、标准、模范。
原型模式的主旨思想即是基于一个现有的对象来构建一个新对象(不是重新new创建),然后在新对象上作相应属性修改等以满足要求。
不用new,有多方面的原因,如有些对象的new操作开销较大,性能不好,如需要的对象类型是运行时决定的,编译时不知道类型,无法new等等。
原型模式也是创建出一个新对象,但不是new出来的,而是直接复制一个现有的对象 即克隆,或拷贝。
对象的拷贝分为浅拷贝和 深拷贝,
浅拷贝:只拷贝简单属性的值和对象属性的地址,不拷贝引用对象本身,即浅拷贝创建出的对象和原对象有相同的属性对象引用;
深拷贝:在浅拷贝基础上,增加了属性引用对象的拷贝,深拷贝创建出的对象引用到的对象和原对象引用的性对象是不相同的对象,为避免被深拷贝过程出现循环引用的情况可以考虑对象序列化解决方案。
场景:商店有一种热销商品,数量有上万之多,甚至更多,但都一模一样,比如形状、大小、颜色、价格、厂商等都相同,唯独编号不同,这种类型的对象如果每个的哦new一次,如此多的对象会造成很大的开销,而且创建的对象几乎都一样,开销不值,最简单高效的方式是:复制,复制出来后改个编号即可。
设计:
示例代码:
interface Toy {
String show();
void setId(String id);
String getId();
void setName(String name);
String getName();
void setSize(String size);
String getSize();
void setColor(String color);
String getColor();
void setCategory(Category category);
Category getCategory();
}
class Category implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class HotSaleToy implements Toy, Cloneable {
private String id;
private String name;
private String size;
private String color;
private Category category;
@Override
public Object clone() throws CloneNotSupportedException {
HotSaleToy newToy = (HotSaleToy) super.clone();
//手动进行 深层 复制,默认新对象和原对象的category是通一个,因为默认只复制一个引用,不复制引用的对象。
// newToy.setCategory((Category) category.clone());
return newToy;
}
@Override
public String getId() {
return id;
}
@Override
public String show() {
return java.text.MessageFormat.format("HotSaleToy'{'name=''{0}'', size=''{1}'', color=''{2}'''}'", name, size, color);
}
public void setId(String id) {
this.id = id;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
@Override
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public Category getCategory() {
return category;
}
@Override
public void setCategory(Category category) {
this.category = category;
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
HotSaleToy hotSaleToy = new HotSaleToy();
hotSaleToy.setId("1");
hotSaleToy.setName("Genius");
hotSaleToy.setSize("5L");
hotSaleToy.setColor("orange");
hotSaleToy.setCategory(new Category());
Toy toy = hotSaleToy;
Toy newToy = (Toy) hotSaleToy.clone();// 以hotSaleToy为模板,复制产生新的对象,十分快速
newToy.setId("2"); // 定制 修改,以满足需求
System.out.println("玩具描述是否一样:" + (toy.show().equals(newToy.show())));
System.out.println("玩具编号是否一样:" + (toy.getId().equals(newToy.getId())));
// 如果没有手动进行属性复制,则为true,看HotSaleToy.clone()实现
System.out.println("玩具种类是否一样:" + (toy.getCategory() == newToy.getCategory()));
System.out.println("是否是同一个对象:" + (toy == newToy));
}
}