首页 > 其他分享 >(七)原型模式

(七)原型模式

时间:2022-11-15 20:46:08浏览次数:40  
标签:clone name age 模式 原型 User public String

1 概述

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

  • 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

  • 一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高。

  • 不用重新初始化对象,而是动态地获得对象运行时的状态。

2 浅复制与深复制

  • 浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。但我们可能更需要这样的一种需求,把要复制的对象所引用的对象都复制一遍。

  • 深复制,深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

Java中的clone方法:clone方法返回与当前对象的一个副本对象。可以通过操作副本对象而不影响当前对象。使用clone方法需要实现Cloneable接口。并重写Object方法中的clone方法。

  • 代码示例

User.java

public class User implements Cloneable {
    public int age;
    public String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

Test.java

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user01 = new User(11,"小明");
        User user02 = user01;
        User user03 = (User)user01.clone();
        user01.age = 12;
        user01.name = "小刚";
        System.out.println(user01.toString());
        System.out.println(user02.toString());
        System.out.println(user03.toString());
    }
}

Test.java

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user01 = new User(11,"小明");
        User user02 = user01;
        User user03 = (User)user01.clone();
        user01.age = 12;
        user01.name = "小刚";
        System.out.println(user01.toString());
        System.out.println(user02.toString());
        System.out.println(user03.toString());
    }
}

输出入下

User{age=12, name='小刚'}
User{age=12, name='小刚'}
User{age=11, name='小明'}

Process finished with exit code 0

3 示例

  • 目标:简历的深复制实现
  • 思路:采用原型模型,但是对象成员要采用深复制。

image

工作经历类

public class WorkExperience implements Cloneable {
    private String workDate;
    private String company;

    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;
    }

    // “工作经历”类实现克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

简历类

public class Resume implements Cloneable {
    private String name;
    private String sex;
    private int age;
    private WorkExperience work;

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

    // 提供clone方法调用的私有构造函数,以便克隆“工作经历”的数据
    private Resume(WorkExperience work) throws CloneNotSupportedException {
        this.work = (WorkExperience) work.clone();
    }

    // 设置个人信息
    public void setPersonalInfo(String sex, int age) {
        this.sex = sex;
        this.age = age;
    }

    // 设置工作经历
    public void setWorkExperience(String workDate, String company) {
        this.work.setWorkDate(workDate);
        this.work.setCompany(company);
    }

    public void display() {
        System.out.println(String.format("%s %s %s", name, sex, age));
        System.out.println(String.format("工作经历:%s %s", work.getWorkDate(), work.getCompany()));
    }

    // 调用私有的构造方法,让“工作经历”克隆完成,
    // 然后再给这个“简历”对象的相关字段赋值,
    // 最终返回一个深复制的简历对象
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Resume obj = new Resume(work);
        obj.name = this.name;
        obj.sex = this.sex;
        obj.age = this.age;
        return obj;
    }
}

客户端

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Resume a = new Resume("小明");
        a.setPersonalInfo("男",24);
        a.setWorkExperience("2018-2022","A公司");
        Resume b = (Resume) a.clone();
        b.setWorkExperience("2017-2019", "B公司");
        Resume c = (Resume) a.clone();
        c.setPersonalInfo("男",25);
        c.setWorkExperience("2019-2022","C公司");
        a.display();
        b.display();
        c.display();
    }
}

输出入下

小明 男 24
工作经历:2018-2022 A公司
小明 男 24
工作经历:2017-2019 B公司
小明 男 25
工作经历:2019-2022 C公司

标签:clone,name,age,模式,原型,User,public,String
From: https://www.cnblogs.com/dalelee/p/16892777.html

相关文章

  • rabbitmq集群部署-镜像模式
    一、环境RabbitMQ与Erlang的兼容关系详见:https://www.rabbitmq.com/which-erlang.htmlrabbitmq集群最好是奇数节点,所以一般需要3台设备以上。操作系统:CentOS7Erlang:erl......
  • (五)工厂方法模式
    工厂方法模式(FactoryMethod),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。与简单工厂模式的区别:简单工厂模式的最大......
  • js对象和原型、原型链的关系
    JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯......
  • js异步编程的三种模式
    写在前面javascript语言的执行环境是"单线程"(singlethread),就是指一次只能完成一件任务。如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任务,以此类推。......
  • RabbitMq简单模式
    RabbitMq简单模式定义一个生产者,负责发送消息到队列中/***@authorzjh*生产者发信息*/publicclassProducer{/***队列名称*/public......
  • Qt音视频开发02-海康sdk解码(支持句柄/回调/gpu模式/支持win/linux)
    一、前言为何还要选用使用海康sdk,之前不是ffmpeg已经牛皮吹上天了吗?这个问题问得好,那是因为无论ffmpeg也好还是vlc/mpv之类的,都是实现的播放相关,不同的监控硬件厂家对应设......
  • 对称加密模式-CipherMode
    原文:https://blog.csdn.net/zfive5/article/details/1428173System.Security.Cryptography加密算法主要分为:l       散列算法(MD5/SHA1/RIPEMD160/SHA256/S......
  • 04.建造者模式
    建造者模式在工厂模式中,关注的是谁创建了这个产品,在建造者模式中,这个产品会有多个复杂工序,例如组装电脑,提供了一个builder类来管理这个组装过程//抽象buildernamespac......
  • 03.抽象工厂模式
    抽象工厂模式AbstractFactoryPattern在简单工厂之后变化得到了工厂方法模式(A工厂生产商品a,B工厂生产商品b),不同的工厂生产不同的商品还有其他变化,现在有一下场景工厂A......
  • 哨兵模式
    1、什么是哨兵模式反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库2、怎么玩1、调整主从服务器为一主二仆模式,6379主、6380、6381仆2......