欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-20 22:05:28
简单来说,通过复制的方式创建对象。 【举个栗子】:点外卖的收货地址 ......

什么是原型模式?

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


原型模式的应用场景

复杂结构对象的创建。

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


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


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

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

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


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

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

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


撸段代码试试看:

思路:

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

输出结果:

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