听完二手玫瑰,倍儿精神,12:43,再更一波
原型模式,是通过复制而不是new生成实例的模式。一般情况下,我们会使用new 类名()来创建实例,但有时我们不能根据类来生成实例,而是通过现有的实例来生成新的实例。详细介绍可以查阅《图解设计模式》第六章Prototype模式。
有的东西还是表达不出来了,直接上代码吧:
public interface Product extends Cloneable{ //继承空接口Cloneable 为说明该接口是可clone的 否则会报错
public abstract void use(String s);
public abstract Product createClone();
}
首先是Product接口,后面的两个类都会实现它,该接口继承了Cloneable接口,在源码中可以看到Cloneable是个空接口,它在此的作用就是表示一下实现该接口的类可以使用clone()方法进行复制操作,clone()方法定义在Object上。Product接口上的createClone()方法就是用来复制实例的方法。
再来看Manager类:
import java.util.HashMap;
/**
* @author lenovo
* @title: Manager
* @projectName LearnDesignMode
* @description: TODO
* @date 2022/5/523:53
*/
public class Manager {
private HashMap showcase = new HashMap();
public void register(String name, Product proto) {
showcase.put(name, proto);
}
public Product create(String protoName) {
Product p = (Product)showcase.get(protoName);
return p.createClone();
}
}
将来需要复制实例的对象在创建之后必须使用Manager进行register(注册),当需要复制实例时,传入约定好的参数以便进行create()。
接下来再看两个实现Product的具体子类:
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 p = null;
try {
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
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() {
Product p = null;
try {
p = (Product)clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
测试一下:
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
UnderlinePen upen = new UnderlinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong message", upen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
Product p1 = manager.create("strong message");
//Product p1 = upen.createClone();
p1.use("Hello, world");
Product p2 = manager.create("warning box");
p2.use("Hello, world");
Product p3 = manager.create("slash box");
p3.use("Hello, world");
}
}
结果如下:
"Hello, world"
~~~~~~~~~~~~
****************
* Hello, world *
****************
/ Hello, world /
可以明显看到,原型模式还是由clone()方法实现的,有兴趣大家可自行查阅,clone()方法是native的,可找下具体实现。哦对,这里还分浅拷贝,深拷贝,和JS是差不多的。