Java设计模式之创建型-原型模式(UML类图+案例分析)

这篇具有很好参考价值的文章主要介绍了Java设计模式之创建型-原型模式(UML类图+案例分析)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析 

4.1、通用实现(浅克隆)

4.2、深克隆

五、总结


一、基础概念

原型模式通过复制已有对象作为原型,通过复制该原型来返回一个新对象,而不是新建对象,说白了就是不断复制相同的对象罢了。

二、UML类图

Java设计模式之创建型-原型模式(UML类图+案例分析),Java,设计模式,java,设计模式,原型模式

三、角色设计

角色 描述
抽象原型类 规定了具体的原型对象必须实现的clone()方法
具体原型类 实现抽象原型类的clone()方法,它是可以为复制的对象
客户端 通过请求从原型对象再创建对象来创建新对象

四、案例分析 

4.1、通用实现(浅克隆)

定义一个学生类,实现Cloneable接口并重写clone方法。

super.clone()是基于对象在内存中的二进制位面值进行复制的一种浅拷贝实现。它的优点是效率高,不需要进行逐字段复制,因此不会调用对象的构造函数,也就是不需要经历初始化的过程。

    @Override
    protected Student clone(){
        Student student = null;
        try {
            student = (Student) super.clone();
        }catch (Exception e){
            e.printStackTrace();
        }
        return student;
    }

其内部属性有name和Teacher类,实现有参构造,get和set方法,重写toString()方法。 

public class Student implements Cloneable{

    private String name;

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

    private Teacher teacher;

    public Student(String name, Teacher teacher) {
        this.name = name;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    protected Student clone(){
        Student student = null;
        try {
            student = (Student) super.clone();
        }catch (Exception e){
            e.printStackTrace();
        }
        return student;
    }
}

客户端:

public class Client {

    public static void main(String[] args) {
        Teacher teacher = new Teacher("赵老师");
        Student student = new Student("李四",teacher);
        Student clone = student.clone();
        clone.getTeacher().setName("老王老师");
        System.out.println(student);
        System.out.println(clone);
    }

}

运行结果如下:

Java设计模式之创建型-原型模式(UML类图+案例分析),Java,设计模式,java,设计模式,原型模式

运行完毕以后会发现一个问题,就是我克隆出来的学生换了新的老王老师以后,怎么原来学生对象的老师也变成了老王老师,这明显不对呀!

从运行的结果上分析,应该是teacher共用同一个内存地址,意味着复制的不是值,而是引用的地址,这正是浅拷贝的特征:

1、对基本数据类型进行值复制

2、对引用类型仅复制引用,没有复制引用的对象

解决办法是在clone时,需要深拷贝teacher对象,断开student和clone的teacher对象引用关系,使两者独立。

4.2、深克隆

Student类需要实现Serializable接口,并自定义了deepClone方法实现深克隆,每一行代码解释如下:

1、创建字节数组输出流,用于存放序列化后的二进制数据。

ByteArrayOutputStream bos = new ByteArrayOutputStream();

2、 基于字节数组输出流创建对象输出流,用于序列化对象。

ObjectOutputStream oos = new ObjectOutputStream(bos);

3、 将当前对象写入对象输出流进行序列化,序列化后的二进制数据存入字节数组输出流。

oos.writeObject(this);

4、获取字节数组输出流中的数据(序列化后的二进制数据),封装为字节数组输入流。

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

5、基于字节数组输入流创建对象输入流,用于反序列化对象。

ObjectInputStream ois = new ObjectInputStream(bis);

6、从对象输入流中读取流数据并反序列化生成对象,返回反序列化得到的学生对象副本。

return (Student) ois.readObject();

完整的关键代码如下: 

public class Student implements Cloneable, Serializable {
    
          
    //构造、get和set方法、toString()方法省略

    public Student deepClone(){
        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 (Student) ois.readObject();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

}

总结起来,这段代码使用了序列化和反序列化来实现对象的深克隆,核心思路是将对象写入流,然后从流里再读出来克隆对象。 

同时Teacher类也需要实现Serializable序列化接口,关键代码如下:

public class Teacher implements Serializable {}

但不需要实现深克隆,原因如下:

在通过序列化实现Student深克隆时,会自动将Student对象所引用的Teacher对象全部序列化,并在反序列化时重新创建出一个新的Teacher对象。

Teacher对象已经在这个序列化/反序列化的过程中被自动深克隆了,不需要再单独实现深克隆方法。

客户端:

public class Client {

    public static void main(String[] args) {
        Teacher teacher = new Teacher("赵老师");
        Student student = new Student("李四",teacher);
        Student clone = student.deepClone();
        clone.getTeacher().setName("老王老师");
        System.out.println(student);
        System.out.println(clone);
    }

}

运行结果如下: 

Java设计模式之创建型-原型模式(UML类图+案例分析),Java,设计模式,java,设计模式,原型模式

五、总结

优点:

1、避免重复创建成本高的对象。

2、客户端可以直接获得对象副本,不需要知道如何创建。

3、可以动态添加或者修改复制逻辑。

缺点:

1、需要为每一个类配置一个克隆方法。

2、复制对象的成本也存在,特别是深拷贝。

3、需要注意隔离对象状态,避免相互影响。

应用场景:

1、对象的创建成本比较大,可以通过复制原型对象避免重复创建。

2、需要重复创建相似对象时可以考虑原型模式。

3、需要避免使用子类式继承改变对象结构时。

符合的设计原则:

1、开闭原则(Open Closed Principle)

原型模式通过克隆生成新对象,而不需要修改源对象的类,对扩展开放,对修改关闭。

2、组合复用原则(Composite Reuse Principle)

原型模式复用的是对象,不需要通过继承创建子类,可以更灵活地复用对象。

3、单一职责原则(Single Responsibility Principle)

原型类只需要实现Cloneable接口,不需要其他责任,专注于复制自己。

4、里氏替换原则(Liskov Substitution Principle)

原型模式生成的对象和原对象是一致的,扩展也不会破坏原有系统。

5、依赖倒转原则(Dependency Inversion Principle)

客户端只依赖于原型类的接口,不依赖具体实现,降低了依赖。

原型模式通过对象复制获取实例,避免重复创建开销大的对象,是一种快速获取对象副本的模式,但需要注意副本状态的一致性管理。文章来源地址https://www.toymoban.com/news/detail-551839.html

到了这里,关于Java设计模式之创建型-原型模式(UML类图+案例分析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java设计模式之结构型-桥接模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、支付方式 4.2、支付渠道  五、总结 桥接模式(Bridge Pattern)是一种结构型设计模式,其主要目的是“将抽象部分与实现部分分离,使它们都可以独立地变化”。 桥接模式的核心思想是把抽象(abstraction)与实现

    2024年02月13日
    浏览(43)
  • Java设计模式之结构型-组合模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、菜单遍历  五、总结  组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。 角色 描述

    2024年02月16日
    浏览(50)
  • Java设计模式之行为型-责任链模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、在Java中实现 4.2、在SpringBoot中实现  五、总结  责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行发送。请求会被链上每个处理者处理,直到请求被处理完毕。该模式主要解决的是请求的发送者和

    2024年02月15日
    浏览(39)
  • Java设计模式之行为型-迭代器模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结 迭代器模式是一种常用的设计模式,它主要用于遍历集合对象,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 举个简单的比喻,聚合对象像一个存放苹果的篮子,迭代

    2024年02月16日
    浏览(43)
  • Java设计模式之结构型-享元模式(UML类图+案例分析)

    目录 一、基本概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、游戏角色 五、总结 享元模式是一种结构型设计模式,主要用于减少创建大量相似对象所占用的内存,它通过共享技术来有效支持大量细粒度的对象。 角色 描述 抽象享元角色 定义出对象的外部状

    2024年02月16日
    浏览(45)
  • Java设计模式之结构型-装饰器模式(UML类图+案例分析)

    目录 一、基本概念 二、UML类图 三、角色设计 四、代码实现 案例一 案例二  五、总结  装饰器模式是指不必在改变原有的类和不使用继承的情况下,动态扩展一个对象的功能。 角色 描述 抽象构件 是一个接口或者抽象类,定义我们最核心的对象 具体构件 抽象构件的实现,

    2024年02月11日
    浏览(35)
  • Java设计模式之行为型-备忘录模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结  备忘录模式是一种行为型设计模式,它允许保存一个对象的内部状态到一个备忘录对象中,这样就可以在需要的时候恢复这个对象的状态了,同时又不违反封装性原则。 这个模式的核心就是备忘录对象,

    2024年02月16日
    浏览(38)
  • Java设计模式之行为型-访问者模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结 访问者模式是一种对象行为型设计模式,它能够在不修改已有对象结构的前提下,为对象结构中的每个对象提供新的操作。 访问者模式的主要作用是把对元素对象的操作抽象出来封装到访问者类中,这样就

    2024年02月16日
    浏览(54)
  • Java设计模式之UML类图

    UML图有很多种,但是并非必须掌握所有的UML图,才能完整系统分析和设计工作。一般说来,在UML图中,只要掌握类图、用例图、时序图的使用,就能完成大部分的工作。对于程序员来说,最频繁使用的莫过于类图。因此,这里我只讲解UML类图。 类图是面向对象系统建模中最常

    2024年02月03日
    浏览(41)
  • Java设计模式之责任链模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设计模式之责任链模式 OA系统采购审批需求 传统方案解决OA系

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包