设计模式-原型模式
定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
通用类图
角色
Prototype(原型)
负责定义用于复制现有实例来生成新实例的方法。
ConcretePrototype(具体的原型)
负责实现复制现有实例并生成新实例的方法。
Client(使用者)
负责使用复制实例的方法生成新的实例。
原型对象必须继承
Cloneable
接口,该接口为标记接口,这样的接口没有抽象方法,该接口只是被用来标记 “ 可以使用clone方法进行复制 ”。
实现
public interface Product extends Cloneable {
void use(String s);
Product createClone();
}
public class MessageBox implements Product {
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
public void use(String s) {
int length = s.getBytes().length;
for (int i = 0; i < length +4 ; i++) {
System.out.print(decochar);
}
System.out.println("");
System.out.println(decochar + " " + s + " " + decochar);
for (int i = 0;i<length+4;i++) {
System.out.print(decochar);
}
System.out.println("");
}
@Override
public Product createClone() {
Product product = null;
try {
product = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return product;
}
}
public class UnderlinePen implements Product {
private char ulchar;
public UnderlinePen(char ulchar) {
this.ulchar = ulchar;
}
@Override
public void use(String s) {
int length = s.getBytes().length;
System.out.println("\"" + s + "\"");
System.out.print(" ");
for (int i =0;i<length;i++) {
System.out.print(ulchar);
}
System.out.println("");
}
@Override
public Product createClone() {
System.out.println("UnderlinePen createclone");
Product product = null;
try {
product = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return product;
}
}
public class Manager {
private HashMap<String,Product> showcase = new HashMap();
public void register(String name, Product product) {
showcase.put(name, product);
}
public Product create(String name) {
Product product = (Product) showcase.get(name);
return product.createClone();
}
}
public static void main(String[] args) {
Manager manager = new Manager();
UnderlinePen pen = new UnderlinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong message", pen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
Product product1 = manager.create("strong message");
product1.use("hello wold.");
Product product2 = manager.create("warning box");
product2.use("hello world.");
Product product3 = manager.create("slash box");
product3.use("hello world.");
}
现在可以在原型对象中生成clone方法实体。
clone方法进行的是浅复制
clone 方法所进行的复制只是将被复制实例的字段值直接复制到新的实例中。它并没有考虑字段中所保存的实例的内容。如,字段中保存的是数组时,使用clone方法进行复制,则只会复制该数组的引用,并不会一 一复制数组中的元素。
如果clone无法满足需求时,可以实现重写clone方法。
优点
- 性能优良:原型模式是在内存二进制流的拷贝,比直接new一个对象性能好很多。
- 逃避构造函数的约束:直接在内存中拷贝,构造函数是不会执行的。