设计模式之原型模式

相关点:

  • apache中反射实现原型模式 BeanUtils

  • jdk clone克隆(浅拷贝)

  • 在Spring中Bean对象配置中的scope=“prototype”,每次使用对象之前,都会
    创建一个对象,并且会将依赖关系完整的赋值给新创建的对象
    Spring 默认是单例模式

浅拷贝: 如果是复制的是 引用类型,那么复制的就是引用类型的地址,并没有重新新建一个单独的引用类型,后面如果复制的新对象修改了这个引用的值就会影响之前的原型对象。基本类型没有什么影响,就是简单的赋值

深拷贝: 完完全全的把对象给复制了一遍,而不会像浅拷贝那样复制引用地址

1.使用序列化完成深克隆

需要实现Serializable接口,浅拷贝需要实现clone接口,重写clone方法
举例:
java提供clone方法就是浅拷贝

package com.prototype;

import java.io.*;

public class ProtoType implements Cloneable,Serializable{

    private String name;

    private User user;
    
   //可以重写clone方法	,浅拷贝
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    //深度克隆
    public Object deepClone01() throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream  oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        Object object = ois.readObject();
        return object;
    }
//笨的深度克隆
    public ProtoType deepClone02() throws Exception {
        ProtoType protoTypeClone = new ProtoType();
        protoTypeClone.name = this.name;
        protoTypeClone.setUser(new User(this.getUser().getuName(),this.getUser().getAge()));
        return protoTypeClone;
    }
    ...get,set方法省略
}

User类

public class User implements Cloneable,Serializable {

    private String uName;

    private int age;
    public User() {

    }
    public User(String uName, int age) {
        this.uName = uName;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    ...get,set方法省略
}

测试:

package com.prototype;

public class TestProtoType {

    public static void main(String[] args) throws Exception {

        ProtoType protoType = new ProtoType();
        protoType.setName("ws");
        protoType.setUser(new User("vison",18));
        ProtoType protoTypeClone = (ProtoType) protoType.clone();
        ProtoType protoTypeDeepClone01 = (ProtoType) protoType.deepClone01();
        ProtoType protoTypeDeepClone02 =  protoType.deepClone02();


        System.out.println("浅客隆"+(protoType == protoTypeClone));  //结果是false ,new一个新对象
        System.out.println("浅客隆"+(protoType.getUser() == protoTypeClone.getUser())); //结果是true

        System.out.println("深客隆01"+(protoType == protoTypeDeepClone01));//结果是false 
        System.out.println("深客隆01"+(protoType.getUser() == protoTypeDeepClone01.getUser()));//结果是false 

        System.out.println("深客隆02"+(protoType == protoTypeDeepClone02));//结果是false
        System.out.println("深客隆02"+(protoType.getUser() == protoTypeDeepClone02.getUser()));//结果是false 

    }
}
2.使用笨循环赋值

这个其实就是把所有组合的引用类型都重新赋值,一直赋值到基本类型为止
如上面的这个方法。

//笨的深度克隆
    public ProtoType deepClone02() throws Exception {
        ProtoType protoTypeClone = new ProtoType();
        protoTypeClone.name = this.name;
        protoTypeClone.setUser(new User(this.getUser().getuName(),this.getUser().getAge()));
        return protoTypeClone;
    }

当然还有很多种方式实现。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值