原型模式

原型模式
  • 简化创建对象过程,提高效率
  • 不用重新初始化对象,而是动态的获取对象运行时的状态
  • 需要为每一个类配备一个克隆方法,对已有的类进行改造时,需要修改其源码,违背了ocp原则,需要注意。
浅拷贝
  • 数据类型为引用类型的的成员变量,比如数组,类对象等,浅拷贝只会进行引用传递,不会对其进行复制
  • 默认使用clone()方法来实现
Cat类
public class Cat implements Cloneable{
    private String name;
    private int age;
    private Cat friend;

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

    public Cat getFriend() {
        return friend;
    }

    public void setFriend(Cat friend) {
        this.friend = friend;
    }

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

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

    @Override
    protected Object clone()  {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

}


测试类
/**
 * 原型模式
 */
public class Prototype {
    public static void main(String[] args) {
        Cat cat = new Cat("珊珊",17);
        cat.setFriend(new Cat("小王",20));
        System.out.println("属性对象的hashcode: "+cat.getFriend().hashCode());

        //复制
        Cat cat1 = (Cat) cat.clone();
        Cat cat2 = (Cat) cat.clone();
        Cat cat3 = (Cat) cat.clone();
        Cat cat4 = (Cat) cat.clone();

        System.out.println("属性对象的hashcode: "+cat1.getFriend().hashCode());
        System.out.println(cat.toString());
        System.out.println("对象的hashcode:"+cat.hashCode());
        System.out.println("对象的hashcode:"+cat2.hashCode());
        System.out.println(cat1.toString());
        System.out.println(cat2.toString());

    }
}

输出结果
属性对象的hashcode: 460141958
属性对象的hashcode: 460141958
Cat{name='珊珊', age=17, friend=Cat{name='小王', age=20, friend=null}}
对象的hashcode:1163157884
对象的hashcode:1956725890
Cat{name='珊珊', age=17, friend=Cat{name='小王', age=20, friend=null}}
Cat{name='珊珊', age=17, friend=Cat{name='小王', age=20, friend=null}}

会发现friend对象属性所指向的是同一个对象,也就是对于这个属性并没有进行复制。

深拷贝
调用clone

Cat类

package com.rikka.prototype;

public class Cat implements Cloneable{
    private String name;
    private int age;
    private Dog friend;

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

    public Dog getFriend() {
        return friend;
    }

    public void setFriend(Dog friend) {
        this.friend = friend;
    }

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

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

    @Override
    protected Object clone()  {
        Object clone = null;
        try {
            clone = super.clone();
            Cat cat = (Cat) clone;
            cat.friend =(Dog) friend.clone();
            return cat;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

}

Dog类

package com.rikka.prototype;

public class Dog implements Cloneable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

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

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

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

测试类

package com.rikka.prototype;

/**
 * 原型模式
 */
public class Prototype {
    public static void main(String[] args) {
        Cat cat = new Cat("珊珊",17);
        cat.setFriend(new Dog("小王",20));
        System.out.println("属性对象的hashcode: "+cat.getFriend().hashCode());

        //复制
        Cat cat1 = (Cat) cat.clone();


        System.out.println("属性对象的hashcode: "+cat1.getFriend().hashCode());
        System.out.println(cat.toString());
        System.out.println("对象的hashcode:"+cat.hashCode());
        System.out.println(cat1.toString());
        System.out.println("对象的hashcode:"+cat1.hashCode());

    }
}

此时Cat中的Dog对象属性也被复制(hashCode不同)

序列化(推荐使用)

Dog与Cat类都实现序列化接口(Serializable)
deepCopy()方法如下

    public Object deepCopy(){
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;


        try {
            //序列化
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this); //以对象流的方式输出当前对象


            //反序列化
            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            Object object = objectInputStream.readObject();
            return object;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                byteArrayOutputStream.close();
                objectOutputStream.close();
                byteArrayInputStream.close();
                objectInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return null;
    }

测试:

    /**
     * 原型模式
     */
    public class Prototype {
        public static void main(String[] args) {
            Cat cat = new Cat("珊珊",17);
            cat.setFriend(new Dog("小王",20));
            System.out.println("属性对象的hashcode: "+cat.getFriend().hashCode());

            Cat cat1 = (Cat) cat.deepCopy();
            System.out.println("属性对象的hashcode: "+cat1.getFriend().hashCode());

            System.out.println(cat.hashCode());
            System.out.println(cat1.hashCode());
        }
    }

打印结果:

属性对象的hashcode: 460141958
属性对象的hashcode: 363771819
325040804
2065951873
spring 获取bean 对象时有用到原型模式
<bean id="" class="" scope="protype"/>  //scope 使用原型模式创建bean对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值