原型模式

概念:该模式有一个样板实例,这个被克隆的实例就是我们说的“原型”。说白了就是有一个对象A,我们要操作的时候拷贝A得到一个A的副本B,这个A就称之为原型。我们操作的时候是对B做操作,这样就不会影响到原型A。

应用场景:

  1. 类初始化的时候需要消耗的资源比较多,这些资源包括数据、硬件等资源,通过原型拷贝可以避免这些消耗。
  2. 通过new产生一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
  3. 一个对象需要供给其他对象访问,而且各个对象可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
  4. 构造函数比较复杂
  5. 循环体中有大量对象

优点:

  1. 性能优良,Java自带额原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上升了许多。
  2. 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保护起来,简化了创建过程。

缺点:

  1. 必须具备克隆(或拷贝)的方法(如实现cloneable接口)。
  2. 当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
  3. 深拷贝,浅拷贝需要运用得当(深拷贝方法一般都要自己实现,直接调用clone()方法都是浅拷贝)。

拷贝:

  1. 浅拷贝:只拷贝基本类型,不会拷贝引用类型,引用类型复制之后,还是共同引用,但是String类型除外,因为String是被final修饰的,所以各个对象之间互不影响。
  2. 深拷贝:会在计算机中开辟一个新的内存地址,所以深拷贝对象都是新的对象。

注意:原型模式和单例模式不能同时使用,他们是相背的,单例模式是使构造方法私有化,而原型模式根本不需要构造方法,所以在设计程序的时候,如果使用单例模式,我们一般就不能实现cloneable接口,否则可能会带来其他问题(如可以克隆出很多对象,破坏单例)。

原型模式demo:

public class Book implements Cloneable{
    //名称
    private String title;
    //图片
    private ArrayList<String> listImg = new ArrayList<>();

    public void addImg(String imgName){
        listImg.add(imgName);
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<String> getListImg() {
        return listImg;
    }

    public void setListImg(ArrayList<String> listImg) {
        this.listImg = listImg;
    }

    public void showBook(){
        System.out.println("..................start......................");
        System.out.println("title:" + title);
        listImg.stream().forEach(img -> System.out.println("img name" + img));
        System.out.println("..................end......................");
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //浅克隆  默认浅克隆
        Book book = (Book)super.clone();
        //深克隆
        book.listImg = (ArrayList<String>) this.listImg.clone();//这个方法在ArrayList类中,List接口没有这个clone()方法
        return book;
    }
}

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Book book1 = new Book();
        book1.setTitle("图书1");
        book1.addImg("图片1");
        book1.showBook();
        //以原型方式进行复制
        Book cloneBook = (Book) book1.clone();
        book1.setTitle("图书2");
        book1.addImg("图片2");
        cloneBook.showBook();
        book1.showBook();
    }
}

输出结果:

..................start......................
title:图书1
img name图片1
..................end......................

..................start......................
title:图书1
img name图片1
..................end......................

..................start......................
title:图书2
img name图片1
img name图片2
..................end......................

上述代码,定义了一本书,有名称和图片两个属性,标题是String类型的,图片是ArrayList集合,通过浅克隆克隆String类型的title,深克隆克隆ArrayList类型的图片,这样就可以克隆出一个新的对象出来,然后进行赋值比较。通过输出结果可以看出,book1赋值图书1和图片1之后拷贝一个cloneBook对象,然后再对book1对象进行修改,但是此时并不会对cloneBook有影响,也就是说已经是两个不同的对象了。如果使用浅克隆对Arraylist进行操作的话,cloneBook对象的输出应该是:“图书1,图片1,图片2”(只要将“  book.listImg = (ArrayList<String>) this.listImg.clone();” 这句注释即可,可以私下去验证一下)。

ArrayList、 HashMap底层其实也是浅克隆,只是把元素搬了个家,只要实现了cloneable接口的都是浅克隆,如果一个类中又有list又有map那我们不是要一个个去调用,如果引用类型里面又有引用类型,处理起来也是非常麻烦的。所以我们一般使用序列化和反序列化以及JSON转换方式来实习深克隆,这样也比较方便,直接转换就行了。

序列化深克隆方法:

public User deepCloneByIO(){
    try{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);

        return (User) ois.readObject();
    }catch (Exception e){
        e.printStackTrace();
        return null;
    }
}

注意:实现序列化必须要实现Serializable接口,否则会报异常。

使用序列化来实现深克隆带来一系列的问题,会带来一定的性能问题以及占用io,所以一般情况下都使用JSON对象转换来实现深克隆:

public User deepCloneByJson(Object object){
    return JSON.parseObject(JSON.toJSONString(object), User.class);
}

操作起来简单,方便。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值