创建型模式————原型模式(2.3)

什么是原型模式?

简单来说,通过复制的方式创建对象。(被复制的对象可以理解为模板)

原型模式的应用场景

复杂结构对象的创建。

复杂结构对象:可以理解为对象里面还有对象。

【举个栗子】:点外卖的收货地址

收货地址包括姓名,电话和住址。第一次点外卖的时候需要完整的填写这些信息,但是之后点的过程基本上是不用再重新填写这些信息的。试想一下,每次下单之前都要填一遍姓名,电话,详细地址(假设省市已经定位好了)。头大.....而这个场景,正是原型模式的用武之地。

点外卖之前复制上一次填写的地址,直接下单;或者手机号出现变更,修改一下直接更新到模板即可。

原型模式的本质是创建一个对象模板,然后通过复制的方式实现复用。

深拷贝(复杂对象一波带走)

在深拷贝之前,简单聊一下浅拷贝。

以上述收货地址为例,如果只涉及到姓名,电话这些基本数据类型(浅拷贝与深拷贝是基本没有区别的),但是如果涉及到地址这样的引用类型。浅拷贝就会出现问题。浅拷贝对于引用对象,只复制其引用地址。所以复制出来的对象和被复制的对象会指向同一个值。假设你想建立两个收货模板,地址是不同的,那么就只能使用深拷贝了。

撸段代码试试看:

思路:

1.创建Info类和Address类继承Serializable接口,为了后面实现序列化写入内存。(实现平台无关性)

2.Info类还需要继承Cloneable接口,并重写clone()方法,注:protected改为public

3.在clone()方法中添加写入内存和读取的逻辑

4.Info info1 = (Info) info.clone();创建对象,并可做灵活修改。

import java.io.*;

class Address implements  Serializable
{
    private String province;
    private String city;
    private String Street;
    private String door_number;

    public Address(String province, String city, String street, String door_number) {
        this.province = province;
        this.city = city;
        Street = street;
        this.door_number = door_number;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return Street;
    }

    public void setStreet(String street) {
        Street = street;
    }

    public String getDoor_number() {
        return door_number;
    }

    public void setDoor_number(String door_number) {
        this.door_number = door_number;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                ", Street='" + Street + '\'' +
                ", door_number='" + door_number + '\'' +
                '}';
    }
}

class Info implements Cloneable, Serializable   //1.创建一个外卖信息类,继承Cloneable(可复制),Serializable(可序列化)
{
    private String name;
    private String number;

    Address address;

    public String getName() {
        return name;
    }

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

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Info(String name, String number, Address address) {
        this.name = name;
        this.number = number;
        this.address = address;
    }

    @Override
    public String toString() {
        return "Info{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                ", address=" + address +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {    //2.重写clone方法,并把protected换成public
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
                ObjectOutputStream oos = new ObjectOutputStream(out);
                oos.writeObject(this);   //写入内存
                oos.close();

            byte[] bytes = out.toByteArray();
            InputStream in = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(in);
            Object clone = ois.readObject();  //读取内存
            ois.close();

            return clone;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

/*
clone()方法直接复制在内存中已经创建对象的二进制,效率极高!(不需要调用构造器)

protected native Object clone() throws CloneNotSupportedException;
native修饰的方法直接调用底层的C语言

 */
public class MyInfo
{
    public static void main(String[] args) throws CloneNotSupportedException {
        Info info = new Info("shadow","18116207310",new Address("上海","浦东新区","振南路","355"));
        System.out.println(info);
        Info info1 = (Info) info.clone();  //3.复制加强转
        System.out.println(info1);

        System.out.println("//修改电话:");
        Info info2 = (Info) info.clone();
        info2.setNumber("123456789");
        System.out.println(info2);

        System.out.println("//修改地址:");
        Info info3 = (Info) info.clone();
        info3.getAddress().setStreet("西语街");
        info3.getAddress().setDoor_number("666");

        System.out.println(info3);
    }
}

输出结果:

(0)

相关推荐

  • 结合JDK源码看设计模式——原型模式

    定义: 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.不需要知道任何创建的细节,不调用构造函数 适用场景: 类初始化的时候消耗较多资源 new产生的对象需要非常繁琐的过程 构造函数比 ...

  • PHP设计模式之原型模式

    PHP设计模式之原型模式 原型模式其实更形象的来说应该叫克隆模式.它主要的行为是对对象进行克隆,但是又把被克隆的对象称之为最初的原型,于是,这个模式就这样被命名了.说真的,从使用方式来看真的感觉叫克隆 ...

  • 设计模式-原型模式详解

    一.原型模式的概念 原型模式属于创建型设计模式.当要创建的对象类型由原型实例确定时使用它,该实例被克隆以生成新对象. 此模式用于 1.避免客户端应用程序中的对象创建者的子类,如工厂方法模式. 2.避免 ...

  • 面试官:你知道对象的克隆原理吗?

    本文主要内容 背景 先说说生活中三个例子: 西游记中,孙悟空能变身为n多个孙悟空,也就是一个孙悟空克隆为多个孙悟空了. 王者农药中,元歌有个傀儡,这个傀儡我们也可理解为复制的元歌,你把傀儡杀死了,其实 ...

  • 原型模式

    序言:今天我们来聊一下原型模式,我个人认为原型模式的命名不太好理解,称呼其为克隆模式会更妥当一点.原型模式的目的是通过复制一个现有的对象来生成一个新的对象,而不是通过实例化的方法. 原型模式的基本介绍 ...

  • 设计模式-创建型-抽象工厂模式

    前一章节,我们介绍了简单工厂模式以及工厂方法模式,但是这两种模式都存在一定的局限性,只能生产某一类型下的某一种产品,如果需求变更,同类型下出现了不同的产品,比如芝士披萨不仅有口味上的不同,同时存在外观 ...

  • 创建型设计模式--工厂模式、抽象工厂模式

    一.小案例分析 1.功能需求: 实现一个发送信息的功能,要便于扩展与维护. (1)发送信息的工具有很多,比如短信.微信.邮件.QQ等. (2)选择某个工具进行信息发送. 2.小菜鸡去实现: (1)定义 ...

  • 创建型模式之原型模式

    定义与特点 原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象. 在这里,原型实例指定了要创建的对象的种类.用这种方式创建对象 ...

  • 创建型模式之工厂方法

    目录 定义与特点 结构与实现 模式的结构 模式的实现 应用场景 扩展:简单工厂模式 参考文章 定义与特点 工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的 ...

  • 创建型模式之单例模式

    定义与特点 单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式. 例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成 ...

  • 创建型模式

    title: "[设计模式]创建型模式" date: 2016-03-07 18:05 tags: 设计模式 design pattern creational factory m ...

  • 设计模式-创建型-建造者模式

    引言: 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.底盘.发动机.方向盘等各种部件.而对于大部分用户而言,无须知道这些部件的装配细节,也几乎不会 ...

  • 设计模式-创建型-工厂模式

    工厂设计模式: 顾名思义,该模式是用来生产对象的.在面向对象的设计模式中,万物皆对象,若使用new来创建对象,就会对该对象产生强耦合,假如我们需要更换该对象,那么使用该对象的对象都需要进行修改,这显然 ...

  • 创建型模式————建造者模式(2.4)

    什么是建造者模式? 工厂模式聚焦于创建出一个对象,而建造者除此之外还需要为创建的对象赋值. 简单来说,建造者模式=创建对象+属性赋值. 建造者模式应用场景 建造者模式适合创建类中包含多个参数且需要定制 ...