设计模式-原型模式

设计模式-原型模式

1 介绍

原型模式的思想:将一个对象作为原型,对其进行复制、克隆,产生一个与原对象类似的新对象。

  1. 浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建;引用类型,指向的还是原对象所指向的,可以根据hasCode判断。
  2. 深拷贝:将一个对象复制后,无论是基本数据类型或者是引用类型的变量,都是重新创建。
  3. 被拷贝的对象需要实现Cloneable接口。
    简单的说,深拷贝是创建全新的对象,浅对象复制的不彻底。
    注意:被拷贝的对象类,都要继承序列化接口Serializable

2 示例

  1. AbstractCloneable 继承Cloneable, 实现浅拷贝与深拷贝的逻辑
public abstract class AbstractCloneable implements Cloneable, Serializable {

    /**
     * 浅拷贝
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * 深度拷贝
     */

    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);
        return ois.readObject();
    }
}
  1. Car 继承 AbstractCloneable
public class Car extends AbstractCloneable {

    public Car(String name, String color, Person person) {
        this.name = name;
        this.color = color;
        this.person = person;
    }

    private String name;

    private String color;

    private Person person;

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", person.hashCode='" + person.hashCode() + '\'' +
                '}';
    }
}
  1. class Person
public class Person implements Serializable {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

  1. PrototypeCloneFactory 工厂方法
public class PrototypeCloneFactory {

    /**
    * 浅拷贝
    * 反射执行
    */
    public <T> T clone(T clone)  {
        try {
            if(clone instanceof AbstractCloneable) {
                Class aClass = clone.getClass();
                Method cloneMethod = aClass.getMethod("clone");
                return (T)cloneMethod.invoke(clone);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

   /**
    * 深拷贝
    * 反射执行
    */
    public <T> T deepClone(T clone)  {
        try {
            if(clone instanceof AbstractCloneable) {
                Class aClass = clone.getClass();
                Method cloneMethod = aClass.getMethod("deepClone");
                return (T)cloneMethod.invoke(clone);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

  1. client
public class Client {

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person("person");
        Car car = new Car("轿车", "red", person);
        PrototypeCloneFactory prototypeModel = new PrototypeCloneFactory();
        // 浅拷贝
        Car cloneCar = prototypeModel.clone(car);
        // 深度拷贝
        Car deepCloneCar = prototypeModel.deepClone(car);
        System.out.println(car.toString());
        System.out.println(cloneCar.toString());
        System.out.println(deepCloneCar.toString());


    }
}

输出

# 被拷贝对象
Car{name='轿车', color='red', person.hashCode='1554874502'}
# 浅拷贝对象
Car{name='轿车', color='red', person.hashCode='1554874502'}
# 深拷贝对象
Car{name='轿车', color='red', person.hashCode='1072408673'}

结论
浅拷贝复制的不彻底,引用类型指向原对象的引用(地址);深拷贝复制的彻底,成员变量,基本类型、应用类型均创建全新的对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值