JAVA设计模式4:谈谈原型模式在JAVA实战开发中的应用

简介: JAVA设计模式4:谈谈原型模式在JAVA实战开发中的应用

本文讲解了 Java 设计模式中的原型模式,并给出了样例代码,原型模式的主要目的是通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程。

一、谈谈什么是对象克隆?

在学习原型模式之前,首先要理解对象克隆的概念。

在Java中,对象克隆是指创建一个现有对象的副本 \color{red}{对象克隆是指创建一个现有对象的副本}对象克隆是指创建一个现有对象的副本,对象克隆通常用于在不影响原始对象的情况下创建一个相同状态的新对象。

Java中的对象克隆可以通过实现 Cloneable 接口和重写 clone() 方法来实现。

在使用克隆时,可以使用clone()方法创建对象的副本,该方法返回一个新的对象,该对象具有与原始对象相同的属性值。

Java 中的 clone() 方法执行的是浅拷贝,这意味着克隆的对象和原始对象共享相同的引用类型字段,如果需要实现深拷贝,即克隆对象及其所有引用类型字段的副本,就需要在 clone() 方法中进行相应的处理。


二、谈谈什么是深拷贝和浅拷贝,有什么区别?

在Java中,对象拷贝可以分为浅拷贝和深拷贝两种方式 \color{red}{对象拷贝可以分为浅拷贝和深拷贝两种方式}对象拷贝可以分为浅拷贝和深拷贝两种方式,它们之间的区别在于拷贝对象时是否创建了原始对象的副本,以及对引用类型字段的处理方式。

2.1 深拷贝

深拷贝是指创建一个新对象,该对象的字段值与原始对象完全相同,包括引用类型字段。在深拷贝中,不仅复制了对象的基本类型字段,还创建了新的对象来存储引用类型字段的副本。这意味着修改拷贝对象的引用类型字段不会影响原始对象的引用类型字段,因为它们引用的是不同的对象。

2.2 浅拷贝

浅拷贝是指创建一个新对象,该对象的字段值与原始对象完全相同,但对于引用类型字段,它们共享相同的引用。换句话说,浅拷贝只复制了对象中的基本类型字段,而对于引用类型字段,只是复制了引用,没有创建新的对象。

在浅拷贝中,修改拷贝对象的引用类型字段会影响到原始对象的引用类型字段。这是因为原始对象和拷贝对象共享相同的引用,所以它们指向相同的内存地址。

2.3 小节

实现深拷贝的方式有多种,比较常用的方法包括以下 3 33 点。

  • 通过实现 Serializable 接口,使用对象的序列化和反序列化来实现深拷贝。
  • 使用 Cloneable 接口和重写 clone() 方法来实现深拷贝。
  • clone() 方法中,除了调用 super.clone() 复制对象的基本类型字段外,还需要对引用类型字段进行单独的深拷贝处理。

总结起来,浅拷贝只复制对象的基本类型字段和引用类型字段的引用,而深拷贝会复制对象的基本类型字段和引用类型字段的副本。

因此,在需要保留对象独立性和避免原始对象修改的情况下,使用深拷贝是更为合适的选择。


三、如何解决java对象拷贝的性能问题

在Java中,对象拷贝可能面临性能问题,特别是在处理大型对象或复杂对象图时,以下是一些可以帮助解决 Java 对象拷贝性能问题的方法,给同学们提供参考。

  1. 使用原型模式:通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程,从而避免了直接创建新对象的开销,原型模式可以通过实现 Cloneable 接口和重写 clone() 方法来实现。
  2. 使用浅拷贝:如果你只需要复制对象的基本类型字段,并且可以共享引用类型字段,那么浅拷贝是一个更高效的选择,浅拷贝只涉及字段的复制,因此比深拷贝更快。
  3. 使用构造函数:手动编写一个构造函数,以根据原始对象的属性创建新对象,这种方式可以避免调用 clone() 方法或实现 Cloneable 接口的开销。
  4. 使用序列化和反序列化:使用 Java 对象的序列化和反序列化机制可以实现深拷贝,通过将对象序列化为字节流,然后反序列化成新的对象,可以创建对象及其所有引用字段的完全独立副本,但序列化和反序列化也会带来一定的性能开销。
  5. 使用第三方库:有些第三方库提供了更高效的对象拷贝实现,例如 Apache Commons 库提供了 SerializationUtils.clone() 方法,用于快速实现对象的深拷贝。
  6. 使用对象池:如果你需要频繁地拷贝对象,可以考虑使用对象池,对象池在初始阶段创建一组对象,并在需要时从池中获取和返回对象,以避免频繁地创建和销毁对象。
  7. 考虑重构:有时性能问题可能源于对象本身的设计,在某些情况下,可以通过优化对象的结构或减少不必要的字段来改善性能。


四、学习什么是原型模式

原型模式是一种创建型设计模式 \color{red}{原型模式是一种创建型设计模式}原型模式是一种创建型设计模式,其主要目的是通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程

原型模式通过复制现有对象的状态来创建新对象,从而避免了直接创建新对象的开销,原型模式可以通过实现 Cloneable 接口和重写 clone() 方法来实现。

在原型模式中,原型对象作为被复制的对象,可以称为原型。克隆方法是原型模式的核心部分,它定义了如何复制原型对象。通过克隆方法,我们可以创建一个与原型对象具有相同状态的新对象。

原型模式的主要优点是可以在运行时动态创建对象 \color{red}{原型模式的主要优点是可以在运行时动态创建对象}原型模式的主要优点是可以在运行时动态创建对象,避免了显式的实例化过程,提高了创建对象的效率。它还提供了一种简单的方式来创建具有相同状态的对象,通过修改克隆得到的对象,可以满足不同的需求。另外,原型模式也能够隐藏对象的创建细节,使得客户端代码与具体类解耦。

但在使用原型模式需要注意一些问题。首先克隆对象可能包含对其他对象的引用,这可能导致对象图的复制,需要特别小心处理。其次,克隆过程可能会比直接创建对象更复杂,需要对克隆方法进行合理的实现

原型模式提供了一种创建对象的简单而高效的方式,可以在运行时动态地创建具有相同状态的新对象,它在需要创建相似对象或隐藏对象创建细节时非常有用。


五、原型模式上手实战

以下是一个使用原型模式的 Java 代码示例,请同学们复制到本地执行。

// 原型接口
interface Prototype extends Cloneable {
    Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
    private String name;
    public ConcretePrototype(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
// 客户端代码
public class Client {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("Prototype 1");
        System.out.println("Original object: " + prototype.getName());
        ConcretePrototype clonedObject = (ConcretePrototype) prototype.clone();
        System.out.println("Cloned object: " + clonedObject.getName());
        clonedObject.setName("Prototype 2");
        System.out.println("Modified cloned object: " + clonedObject.getName());
    }
}

在上面的示例中,我们定义了一个原型接口 Prototype,其中包含了一个 clone() 方法用于复制自身对象。

然后,我们创建了一个具体的原型类 ConcretePrototype,实现了 Prototype 接口,并重写了 clone() 方法。

在客户端代码中,我们首先创建了一个原型对象 prototype,然后通过调用 clone() 方法来复制原型对象,得到一个克隆对象 clonedObject

通过修改克隆对象的属性,我们可以验证克隆对象和原型对象是相互独立的,互不影响。


六、原型模式的应用场景

原型模式通常在以下 3 33 类开发场景下使用,请同学们有个简单的了解。

  1. 需要创建一个对象的成本较大,例如涉及到数据库操作、网络请求等耗时操作。
  2. 需要创建的对象与已有对象具有相似的属性,只有部分属性需要修改。
  3. 需要隐藏对象的创建细节,使客户端代码与具体类解耦。

当然,还有一些应用场景,需要用到原型模式。

  1. 复杂对象的创建:当创建一个复杂对象的过程很繁琐或耗时时,可以使用原型模式来复制一个已有对象,避免重复创建。
  2. 原型注册表:使用原型模式可以创建一个对象的集合,并在需要时从集合中复制已有对象,提高对象的创建效率。
  3. 工厂方法模式的替代:原型模式可以作为工厂方法模式的替代,当需要创建的对象具有相同的基类或接口,并且只有部分属性需要修改时,原型模式比工厂方法模式更加灵活。

总之,原型模式适用于创建成本高、创建过程复杂或需要隐藏创建细节的对象,通过克隆现有对象来创建新对象,可以提高创建对象的效率,同时也能够灵活地满足不同的需求


七、原型模式面试题

一、什么是原型模式? \color{red}{一、什么是原型模式?}一、什么是原型模式?

原型模式是一种创建型设计模式,通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程。

二、如何实现原型模式? \color{red}{二、如何实现原型模式?}二、如何实现原型模式?

在Java中,可以通过实现Cloneable接口和重写clone()方法来实现原型模式。clone()方法可以复制现有对象的状态,并创建一个与原型对象具有相同状态的新对象。

三、克隆方法与构造方法有什么区别? \color{red}{三、克隆方法与构造方法有什么区别?}三、克隆方法与构造方法有什么区别?

克隆方法是在现有对象的基础上创建一个新对象,而构造方法是通过实例化类来创建新对象。克隆方法可以复制现有对象的状态,而构造方法需要手动设置新对象的状态。

四、原型模式的优点是什么? \color{red}{四、原型模式的优点是什么?}四、原型模式的优点是什么?

原型模式可以在运行时动态创建对象,避免了显式的实例化过程,提高了创建对象的效率。它还提供了一种简单的方式来创建具有相同状态的对象,并能够隐藏对象的创建细节,使得客户端代码与具体类解耦。

五、原型模式的适用场景有哪些? \color{red}{五、原型模式的适用场景有哪些?}五、原型模式的适用场景有哪些?

原型模式适用于创建成本高、创建过程复杂或需要隐藏创建细节的对象。一些常见的应用场景包括复杂对象的创建、原型注册表和作为工厂方法模式的替代。

六、原型模式的局限性是什么? \color{red}{六、原型模式的局限性是什么?}六、原型模式的局限性是什么?

使用原型模式需要注意克隆对象可能包含对其他对象的引用,这可能导致对象图的复制,需要特别小心处理。克隆过程可能会比直接创建对象更复杂,需要对克隆方法进行合理的实现。


相关文章
|
5天前
|
小程序 数据可视化 Java
Java+后端Spring boot 开发的全套UWB定位方案,0.1米高精度定位系统源码
UWB定位系统由硬件定位设备、定位引擎和应用软件组成。该定位系统应用软件支持PC端和移动端访问,并提供位置实时显示、历史轨迹回放、人员考勤、电子围栏、行为分析、智能巡检等功能。定位精度高达10cm,同时具备高动态、高容量、低功耗的优点。应用场景包括:隧道、化工、工厂、煤矿、工地、电厂、养老、展馆、整车、机房、机场等。
28 8
|
5天前
|
Java API C++
Java JNI开发时常用数据类型与C++中数据类型转换
Java JNI开发时常用数据类型与C++中数据类型转换
12 0
|
18小时前
|
传感器 小程序 搜索推荐
(源码)java开发的一套(智慧校园系统源码、电子班牌、原生小程序开发)多端展示:web端、saas端、家长端、教师端
通过电子班牌设备和智慧校园数据平台的统一管理,在电子班牌上,班牌展示、学生上课刷卡考勤、考勤状况汇总展示,课表展示,考场管理,请假管理,成绩查询,考试优秀标兵展示、校园通知展示,班级文化各片展示等多种化展示。
12 0
(源码)java开发的一套(智慧校园系统源码、电子班牌、原生小程序开发)多端展示:web端、saas端、家长端、教师端
|
1天前
|
Prometheus 监控 Cloud Native
Java一分钟之-Micrometer:应用指标库
【6月更文挑战第11天】Micrometer是Java应用的度量库,提供统一API与多监控系统集成,如Prometheus、InfluxDB。它有标准化接口、广泛后端支持、自动配置和多种度量类型。常见问题包括度量命名不规范、数据过载和忽略维度。解决办法包括遵循命名规范、选择重要指标和使用标签。了解API、设计度量策略和选好监控系统是关键。通过正确使用Micrometer,可建立高效监控体系,保障应用稳定性和性能。
10 1
|
1天前
|
NoSQL Java Serverless
Serverless 应用引擎产品使用合集之Java如何使用ScheduledExecutorService来实现定时触发
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
1天前
|
Java Serverless PyTorch
Serverless 应用引擎产品使用合集之如何将本地的Java项目部署到FC当中
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
2天前
|
JavaScript Java Serverless
Serverless 应用引擎操作报错合集之Java函数在运行时出现报错:"operation not permitted",是什么意思
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
3天前
|
安全 Java Android开发
Kotlin与Java:Android开发的双剑合璧
【6月更文挑战第9天】Kotlin和Java在Android开发中形成互补态势。Java凭借广泛社区支持和丰富的类库资源占据主导,但其语法繁琐和空指针问题限制了发展。Kotlin,设计来解决这些问题,以其简洁、安全、高效的特性逐渐兴起。Kotlin的互操作性允许与Java无缝集成,提升开发效率,减少错误。两者结合提高了代码质量和开发者的灵活性,促进了Android开发社区的繁荣。开发者应把握这种"双剑合璧",适应技术发展。
20 10
|
4天前
|
监控 数据管理 Java
智慧城管源码,基于微服务+java+springboot+vue+uniapp开发的城管综合执法系统源码
智慧城管执法系统利用微服务和Java技术提升城市管理水平,涵盖事件处理、投诉、处罚等功能,包含PC和APP源码。系统支持执法APP,便于领导随时随地审批,具备文书模板、地图定位、法规查询等功能。此外,执法办案系统通过监控视频分析事件,实现案件全程闭环管理,包括组织、案件、信用和执法队伍管理,以及法规库等基础支撑。系统旨在优化流程,提高数据管理和效率。
智慧城管源码,基于微服务+java+springboot+vue+uniapp开发的城管综合执法系统源码
|
5天前
|
IDE Java 项目管理
Java入门——Intellij IDEA简介、使用IDEA开发程序、IDEA常用快捷键、IDEA其他操作
Java入门——Intellij IDEA简介、使用IDEA开发程序、IDEA常用快捷键、IDEA其他操作
9 3