原型模式——对象的快速复制


Demo 地址: https://github.com/ooblee/HelloDesignPattern

1. 定义

原型模式(Prototype  Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。

就是对已有实例的直接复制。

对于一些复杂对象,不需要重复配置或者初始化,以当前对象为原型拷贝一个新对象出来。

病毒克隆

2. 设计

原型主要角色:

  • 抽象原型类,声明克隆方法。
  • 具体原型类,实现克隆方法,返回复制对象。
  • 客户类,调用原型进行克隆。

类图如下:

原型模式-类图

2.1. 通用实现

在 clone 方法中创建新对象,然后把内容一个个复制过去。

抽象克隆类,克隆方法为 cloneObject。

public interface IPrototype {

    IPrototype cloneObject();
}

具体实现类,实现克隆方法,会把当前对象的属性拷贝一份过去。

public class Prototype implements IPrototype {

    private String attr;

    public Prototype() {
    }

    public IPrototype cloneObject() {
        Prototype prototype = new Prototype();
        prototype.attr = attr;
        return prototype;
    }

    public void setAttr(String attr) {
        this.attr = attr;
    }

    public String getAttr() {
        return attr;
    }

    @Override
    public String toString() {
        return "attr:" + attr;
    }
}

调用方式,直接使用 cloneObject 生成新对象。

public class TestPrototype {

    public static void main(String[] args) {

        Prototype prototype = new Prototype();
        prototype.setAttr("hello");
        System.out.println(prototype.toString());

        // 复制对象
        IPrototype cloneObject = prototype.cloneObject();
        System.out.println(cloneObject.toString());

    }
}

2.2. Java Clone 方式

Object 已经内置了 clone 的默认实现,本地方法,作用为在内存空间开辟一个新对象,并把属性值复制一份过去。

如果是引用,则把引用复制一份过去,但不会复制引用的对象。

protected native Object clone() throws CloneNotSupportedException;

Java 使用 Cloneable 接口来标记原型类,实现原型模式。

支持克隆的类实现要覆盖 Object 的 clone 方法。

详细步骤如下:

  • 覆盖 Object 的 clone 方法。
  • 在 clone 中调用 super.clone()。
  • 需要实现 Cloneable 标记接口,否则会报异常。

原型类 Prototype:

public class Prototype implements Cloneable {

    private String attribute;

    private ComplexObject complexObject;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Prototype prototype = (Prototype) super.clone();
        prototype.complexObject = (ComplexObject) this.complexObject.clone();
        return prototype;
    }

  	...
}

2.3. 深克隆和浅克隆

Java 的复制都是值复制。

  • 基本类型的话没问题,直接复制一份新的值。
  • 引用类型的话是复制引用,但不会创建新的对象。所以引用会指向堆中的同一个对象。

浅克隆就是只进行值复制,不为引用类型开新对象。直接调用 Object 的 clone 方法。

@Override
protected Object clone() throws CloneNotSupportedException {
	return super.clone();
}

深克隆是引用类型的对象也进行克隆。在 clone 的时候,再调用一下成员变量对象的 clone 方法开辟新的内存。

@Override
protected Object clone() throws CloneNotSupportedException {
	Prototype prototype = (Prototype) super.clone();
	prototype.complexObject = (ComplexObject) this.complexObject.clone();
	return prototype;
}

3. 应用

这些应用场景可以考虑使用:

  • 创建新对象耗时耗资源,但变化较小
  • 需要创建大量相同或者相似的对象
  • 需要保存对象的状态,可以配合备忘录模式实现

4. 特点

4.1. 优势

  • 简化创建:直接复制,提高效率。
  • 接口简单:不需要增加工厂来创建对象。

4.2. 缺点

  • 每个原型类都要实现克隆方法。
  • 深浅克隆要注意。
发布了61 篇原创文章 · 获赞 43 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/firefile/article/details/90311815
今日推荐