原型模式-Java设计模式(七)

202 阅读2分钟

** 2019-12-11 17:45:35 **

原型模式-Java设计模式(七)

原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

主要解决

在运行期建立和删除原型 (个人理解:消息模块的消息记录对象,除了接收人不同,其他字段均相等,可使用,无需频繁new对象)

优缺点

优点: 1、性能提高。 2、逃避构造函数的约束。 缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。

何时使用

1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

关键代码

继承 Cloneable,重写 clone()

注意事项

与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。 浅拷贝实现 Cloneable,重写, 深拷贝是通过实现 Serializable 读取二进制流。

代码

简历类

/**
 * 简历类 - 实现Cloneable,重写clone()
 */
public class Resume implements Cloneable {

    private String date;
    private String name;
    private String content;

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public Object clone() {
        Resume resume = null;
        try {
            resume = (Resume) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return resume;
    }

    @Override
    public String toString() {
        return this.getName() + ",在【" + this.getDate() + "】在【" + this.getContent() + "】干活。";
    }

}

测试

import java.time.LocalDate;
/**
 * 引用方式 和 clone()对比
 */
public class Test {
    public static void main(String[] args) {
        Resume resume = new Resume();
        resume.setDate(LocalDate.now().minusMonths(1).toString());
        resume.setName("aman");
        resume.setContent(999 + "企业");
        System.out.println(resume);

        Resume AAA = resume;
        System.out.println("===========【 1 】============");
        System.out.println("resume:|||" + resume);
        System.out.println("AAA:   |||" + AAA);

        System.out.println("===========【 2 】============");
        // !!!更改任意一个,都会改变 !!!
        //Resume.setContent("????????");
        AAA.setContent("????????");
        System.out.println("resume:|||" + resume);
        System.out.println("AAA:   |||" + AAA);

        System.out.println("===========【 3 】============");
        Resume clone = (Resume) resume.clone();
        System.out.println("resume:|||" + resume);
        System.out.println("AAA:   |||" + AAA);
        System.out.println("clone: |||" + clone);

        System.out.println("===========【 4 】============");
        clone.setContent("clone嘻嘻嘻嘻");
        System.out.println("resume:|||" + resume);
        System.out.println("AAA:   |||" + AAA);
        System.out.println("clone: |||" + clone);

    }
}

/**
 * 克隆多个
 */
public class Test {
    public static void main(String[] args) {
        Resume resume = new Resume();
        resume.setDate(LocalDate.now().minusMonths(1).toString());
        resume.setName("aman");
        resume.setContent(999 + "企业");
        System.out.println(resume);

        int i = 0;
        while (i < 10) {
            System.out.println("=======================");
            i++;
            resume.clone();
            resume.setContent(String.valueOf(i));
            System.out.println(resume);
        }

    }
}

UML结构图

源码 - prototype分支

不同分支对应不同设计模式源码 github.com/nullaman/Ja…