设计模式三 原型模式

0、 基本定义

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

implement Cloneable

不支持 final

BeanUtils copy 有使用反射实现

浅拷贝:字段是值类型,逐位复制;字段是引用类型,复制引用但不复制引用对象。

深拷贝:复制引用对象, 可通过 序列化方式实现。

1、代码参考

Resume.java

public class Resume implements Cloneable, Serializable{

    private String name;
    private String sex;
    private String age;
    private String timeArea;
    private String company;

    private WorkExperience work;

    public Resume(String name) {
        this.name = name;
        work = new WorkExperience();
    }

    public void setPersonalInfo(String sex, String age) {
        this.sex = sex;
        this.age = age;
    }

    public void setWorkExperience(String timeArea, String company) {
        this.timeArea = timeArea;
        this.company = company;

        //深 拷贝
        work.setCompany(company);
        work.setWorkDate(timeArea);
    }

    public void display() {
        System.out.println(String.join(" ", name, sex, age));
        System.out.println("工作经历:" + String.join(" ", timeArea, company                                                                                                 ));
        System.out.println("workExperience:" + String.join(" ", work.getCompany(), work.getWorkDate()                                                                                                 ));
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
//深拷贝 1
    public Object deepClone() throws IOException, ClassNotFoundException {
        // 序列化

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        Resume o = (Resume) ois.readObject();
        return o;
    }

  //深拷贝 2 - 常规
    public Object deepClone2() throws Exception {

        Resume clone = (Resume) super.clone();
        clone.work = (WorkExperience) this.work.clone();
        return clone;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getTimeArea() {
        return timeArea;
    }

    public void setTimeArea(String timeArea) {
        this.timeArea = timeArea;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

WorkExperience.java

public class WorkExperience implements Serializable,Cloneable{

    private String workDate;
    private String company;

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

    public String getWorkDate() {
        return workDate;
    }

    public void setWorkDate(String workDate) {
        this.workDate = workDate;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

Test.java

public class ResumeTest {

    public static void main(String[] args) throws Exception {

        //浅复制
        Resume resume = new Resume("fred");
        resume.setPersonalInfo("male", "29");
        resume.setWorkExperience("1990-2008", "company A");

//        Resume b = (Resume) resume.deepClone();
        Resume b = (Resume) resume.deepClone2();
//        Resume b = (Resume) resume.clone();

        System.out.println("resume == b?" + (resume == b));
        System.out.println("resume.getClass() == b.getClass()?" + (resume.getClass() == b.getClass()));
        b.setWorkExperience("2000-2015"," tongdun");

        Resume c = (Resume) resume.clone();
        c.setPersonalInfo("male", "30");

        System.out.println("===============");
        resume.display();
        System.out.println("===============");
        b.display();
        System.out.println("===============");
        c.display();

        System.out.println("=====deep clone ====");

    }
}

结果:


===============
fred male 29
工作经历:1990-2008 company A
workExperience: tongdun 2000-2015
===============
fred male 29
工作经历:2000-2015 tongdun
workExperience: tongdun 2000-2015
===============
fred male 30
工作经历:1990-2008 company A
workExperience: tongdun 2000-2015

======deep clone=========
fred male 29
工作经历:1990-2008 company A
workExperience:company A 1990-2008
===============
fred male 29
工作经历:2000-2015  tongdun
workExperience: tongdun 2000-2015   //使用深拷贝后
===============
fred male 30
工作经历:1990-2008 company A
workExperience:company A 1990-2008
=====deep clone ====

2 后续

2.1 优点:

》原型模式是在内存 二进制流的拷贝,比new 性能要好

》逃避构造函数的约束

双刃剑

2.2 使用场景

》资源优化场景

- 类初始化需要消耗很多的资源

》性能和安全要求的场景

- 通过new长生一个对象需要非常 繁琐的数据准备或访问权限

》一个对象多个修改者的场景

=========================

persistence 2.  这块语言描述总结不是很好,源于自己也还有些模糊, 待续完善。。。。。

=========================

参考资料:

咕泡学院- 这块讲的一般

《大话设计模式》

《设计模式之蝉》

原文地址:https://www.cnblogs.com/idea-persistence/p/9533254.html

时间: 2024-10-12 04:45:18

设计模式三 原型模式的相关文章

设计模式-05 原型模式(创建型模式)

一 原型模式 原型模式是用于创建重复的对象,同时又能保证性能. 原型模式用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 主要解决: 利用已有的一个原型对象,快速地生成和原型对象一样的实例 关键代码 : 实现克隆操作,在 JAVA 继承 Cloneable,重写 clone() 使用场景: 类初始化需要消化非常多的资源,这个资源包括数据.硬件资源等. 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备以下两个条件: 实现

C#设计模式(6)——原型模式(Prototype Pattern)

一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配了多个一样的类实例对象,然后如果采用工厂模式来创建这样的系统的话,随着产品类的不断增加,导致子类的数量不断增多,反而增加了系统复杂程度,所以在这里使用工厂模式来封装类创建过程并不合适,然而原型模式可以很好地解决这个问题,因为每个类实例都是相同的,当我们需要多个相同的类实例时,没必要每次都使

设计模式-05 原型模式

一 原型模式 1. 定义 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 2. 类图 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备以下两个条件: 实现Cloneable接口.在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法.在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedExce

【设计模式】——原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 下图是原型模式的结构图: 原型模型其实就是一个对象再创建另外一个可定制的对象,而且不需任何创建的细节,我们来看看基本的原型模式代码. //原型类 class Prototype { private: string id; public: Prototype(string id) { this->id=id; } string GetId() { return id; } virtual Protot

大话设计模式_原型模式(Java代码)

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 简单描述:即通过实现接口Cloneable重写方法clone(),使得创建新的拷贝对象不需要一个成员一个成员的重新复制,而且可以提高创建对象的效率 Java中要想实现拷贝使用clone()方法,类必须实现Cloneable接口,并且重写Object类中的clone()方法,调用父类的clone()方法即可实现浅复制 代码如下: WorkExperience类: 1 package com.longsheng.prototy

大话设计模式之原型模式

原型模式 定义: 用原型实例制定创建对象的种类,并通过拷贝这些原型,创建新的对象. 实质: 就是从一个对象在创建另一个可定制的对象,而且不需要知道任何创建的细节. 核心: (1).实现Cloneable接口,可以使用此接口的类上使用clone方法. (2).重写Object类中的clone方法,因为所有类的父类是Object类,Object有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,将clone改为public类型. 结构图: 代

深入浅出设计模式 ------ Prototype(原型模式)之深度克隆

继上篇深入浅出设计模式 ------ Prototype(原型模式)的浅克隆实现, 本文进入Prototype(原型模式)的进阶篇----深度克隆. 深度克隆 ---- 序列化方式实现 把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization).写在流里的是对象的一个克隆(新的, 独立的), 而原对象仍存在于JVM内存模型里.因此, 以下代码采用序列化方式实现深度克隆. 第一步: 将上篇的代码做些许改动, 加入对象引用

设计模式三: 代理模式(Proxy) -- JDK的实现方式

设计模式三: 代理模式(Proxy) -- JDK的实现方式 简介 代理模式属于行为型模式的一种, 控制对其他对象的访问, 起到中介作用. 代理模式核心角色: 真实角色,代理角色; 按实现方式不同分为静态代理和动态代理两种; 意图 控制对其它对象的访问. 类图 实现 JDK自带了Proxy的实现, 下面我们先使用JDK的API来演示代理如何使用, 随后再探究Proxy的实现原理,并自己来实现Proxy. JDK代理类的使用: (InvocationHandler,Proxy) 使用JDK实现的代

图解Java设计模式之原型模式

图解Java设计模式之原型模式 克隆羊的问题 原型模式 - 基本介绍 原型模式在Spring框架中源码分析 浅拷贝的介绍 深拷贝基本介绍 克隆羊的问题 现在有一只羊tom,姓名为 : tom,年龄为 :1,颜色为 :白色,请编写程序创建和tom羊属性完全相同的10只羊. 传统方式解决克隆羊的问题 package com.example.demo.prototype; public class Sheep { private String name; private int age; privat