原型模式(克隆)

目录

1.核心本质

2.适用场景

3.浅拷贝和深拷贝的区别

4.代码举例

1.地址类

2.人员信息类

3.测试类


1.核心本质

1.对象的克隆

2.减少对象创建时间

3.保护对象的复杂性

4.动态配置属性

2.适用场景

对象初始化成本高,需要频繁创建的情况

当一个对象的创建成本比较高,而你又需要频繁地创建这个对象时,使用原型模式可以通过复制现有实例来提高效率,避免每次都进行昂贵的初始化操作。

需要避免构造函数复杂化的情况

如果某个对象的构造函数或者初始化过程比较复杂,而且需要创建多个相似对象,使用原型模式可以简化对象的创建过程,通过复制现有对象来避免复杂的初始化逻辑。

保护性拷贝的需求

当需要创建一个对象,这个对象的数据需要保护不被外部修改,同时又需要在某些时候复制该对象并进行修改时,原型模式可以帮助实现这种保护性拷贝。

动态配置对象的场景

当系统需要动态地配置对象,根据用户或者环境的不同配置创建不同的对象时,原型模式可以作为一种简洁的创建对象方式。

需要避免继承的场景

当类之间的区别仅在于其初始化数据时,可以使用原型模式避免创建多个相似的子类。

3.浅拷贝和深拷贝的区别

浅拷贝:引用复制,引用对象复制引用地址(旧对象或者拷贝对象修改引用对象的值,另外一个对象的对应值也会修改),基础类型复制值。

深拷贝:全新的对象。

4.代码举例

1.地址类

import java.io.Serializable;
/**
 * 不使用序列化或者反序列化,不用实现Serializable接口
 */
public class Adress implements Cloneable, Serializable {
    String city;
    public Adress(String city){
        this.city = city;
    }

    public String getCity() {
        return city;
    }

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

    @Override
    public String toString() {
        return "Adress{" +
                "city='" + city + '\'' +
                '}';
    }

    public Adress clone() throws CloneNotSupportedException {
        return (Adress) super.clone();
    }
}

2.人员信息类

import java.io.*;
/**
 * 不使用序列化或者反序列化,不用实现Serializable接口
 */
public class Person implements Cloneable,Serializable{
    String name;
    int age;
    Adress adress;

    public Person(String name, int age, Adress adress) {
        this.name = name;
        this.age = age;
        this.adress = adress;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Adress getAdress() {
        return adress;
    }

    public void setAdress(Adress adress) {
        this.adress = adress;
    }

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

    /**
     * 浅拷贝    ---引用对象复制引用地址,基础类型复制值
     *         return (Person)super.clone();
     * 深拷贝1   ---重写所有引用对象clone方法
     *         Person person = (Person) super.clone();
     *         person.adress=(Adress) this.adress.clone();
     *         return person;
      */

    public Person clone() {
        //序列化
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(bos);
            objectOutputStream.writeObject(this);
            objectOutputStream.flush();
            objectOutputStream.close();
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            Person person = (Person) objectInputStream.readObject();
            objectInputStream.close();

            return person;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

3.测试类

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("张三",20,new Adress("北京"));
        Person person2 = person1.clone();
        person2.getAdress().setCity("上海");
        System.out.println(person1.toString());
        System.out.println(person2.toString());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值