设计模式是阅读源码的先修课。
Prototype描述了生成实例的一种场景:通过复制生成实例。
具体Demo
https://mp.weixin.qq.com/s/cnRXW5-rA195sCkgiaWsnw
角色1:client
可以通俗的理解为 负责调用
public class Manager {
private HashMap<String,Product> showCase = new HashMap<>();
public void register(String name,Product product){
showCase.put(name,product);
}
public Product createProduct(String name){
Product product = showCase.get(name);
Product clone = product.createClone();
return clone;
}
}
角色2:
原型角色,负责定义方法。什么方法呢,复制现有实例,生成新实例的方法
Cloneable虽然是标记接口,但是也要实现。否则会报错
public interface Product extends Cloneable {
public abstract void use();
public abstract Product createClone();
}
角色3:原型的具体实现类
public class Spark implements Product {
@Override
public void use() {
System.out.println("我是会发光的 Spark");
}
@Override
public Product createClone() {
try {
return (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
为了更接近真实的使用场景,这里我们假设存在2个子类
public class Slash implements Product {
@Override
public void use() {
System.out.println("我是不一样的光 Slash ");
}
@Override
public Product createClone() {
Product clone;
try {
clone = (Product) clone();
return clone;
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return null;
}
}
验证。生成实例不是最终目的,最终还是为了use
public static void main(String[] args) {
Manager manager = new Manager();
Slash slash = new Slash();
manager.register("slash", slash);
Spark spark = new Spark();
manager.register("spark",spark);
Product slash = manager.createProduct("slash");
slash.use();
Product spark1 = manager.createProduct("spark");
spark1.use();
}
为什么要使用这种模式呢?
理由1:当类的生成非常复杂时,这时很费力的生成好了一个实例,在其他的场景又要使用,可以考虑
理由2:解耦框架与生成的实例
想框架不依赖具体的类,就不能指定类名来生成实例,要事先注册一个原型,然后通过复制来生成新的实例
结合Template Method进行demo优化
有没有发现在上面的案例中,子类中的createClone实现是重复的?那该怎么办呢?