设计模式之原型模式

原型模式

简而言之,以clone代替new
适用于大量创建对象/对象依赖对象复杂,以致创建成本高的场景下

利用了所有类都有的clone()方法(继承自Object类),来实现对象的复制,根据类属性是否复制,可分成深拷贝浅拷贝

组成

  1. 原型接口(继承Cloneable接口,该接口是个标记接口,没有任何方法)
  2. 实现原型接口的类
  3. 管理原型对象及clone的类
  4. 使用原型的类

代码示例

原型接口

1
2
3
4
5
// 不实现Cloneable的类在运行clone()方法时,会抛出 CloneNotSupportedException 异常
public interface Product extends Cloneable {
    void use();
    void createClone();
}

实现原型接口的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ProductA implements Product {
    private String name;

    public ProductA(String name) {
        this.name = name;
    }

    @Override
    public void use() {
        System.out.printf("I am product: [%s]!\n", name);
    }

    @Override
    public Product createClone() throws CloneNotSupportedException {
        return (Product) clone();
    }
}

管理原型类clone的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Manager {
    /**
    * 缓存,用hashmap来保存原型对象
    */
    private static Map<String, Product> dict = new HashMap<>();
    public static void register(String name, Product product){
        dict.put(name, product);
    }
    /**
    * 从缓存中取出原型对象,并clone出新对象
    */
    public static Product getClone(String name) throws CloneNotSupportedException {
        Product product = dict.get(name);
        if (product != null) {
            return product.createClone();
        }
        return null;
    }
}

使用者

1
2
3
4
5
6
7
8
9
10
11
12
public class User {
    public static void main(String[] args) throws CloneNotSupportedException {
        Product p1 = new ProductA("p1");
        Product p2 = new ProductA("p2");
        Manager.register("p1",p1);
        Manager.register("p2",p2);
        Product p11 = Manager.getClone("p1");
        Product p22 = Manager.getClone("p2");
        p11.use();
        p22.use();
    }
}

控制台输出:

1
2
I am product: [p1]!
I am product: [p2]!