设计模式之原型模式

C++设计模式——Prototype Pattern原型模式 原型模式是一种创建型设计模式,它允许通过克隆已有对象来创建新对象,从而无需调用显式的实例化过程。原型模式的设计,使得它可以创建一个与原型对象相同或类似的新对象,同时又可以减少对象实例化操作产生的性能开销,使得创建对象的操作更加便捷,它减少了大量不必要的重复工作,并提高了系统性能。当创建对象的操作比较复杂和耗时的时候,原型模式则提供了一个更加高效和简单的创建对象的模式,它可以更加快速的创建对象的副本,且不需要依赖对象的某些实例化步骤,它避免了使用传统的new关键字创建对象实例时的复杂构造过程。 阅读详情

什么是原型模式

    原型模式是指使用原型实例指定创建对象的类型,并通过拷贝这些原型创建新的对象。
    原型模式的原理是将一个原型对象传给要创建的对象,这个要创建的对象通过请求原型对象拷贝自己来实现创建过程。
    原型模式包含以下几个角色:
        Prototype(抽象原型):声明克隆方法的接口,是所有具体类型的公共父类,可以是抽象类也可以是接口,甚至可以是具体实现类。
        ConcretePrototype(具体原型):实现在抽象原型类中什么的克隆方法,在克隆方法中返回自己的一个新的克隆对象。
        Client(客户端):让一个原型对象克隆自身从而创建一个新的对象,在客户端只需要直接实例化或通过工厂方法等方式创建一个原型对象,再通过调用该对象的克隆方法就得到多个相同的对象。
    原型模式中有两种克隆方法,深拷贝和浅拷贝,区别在于是否支持引用类型的成员变量的复制。
        浅拷贝:如果原型对象的成员变量是值类型,则复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。也就是说浅拷贝时,对象被复制时只会复制对象本身和其中包含的值类型的成员变量,而引用类型的成员变量并不会去复制。
        深拷贝:无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。深拷贝将原型对象的所有引用对象也一起复制一份给克隆对象。

原型模式的优缺点

优点
  1. 当创建一个对象实例较为复杂时,使用原型模式可以简化创建过程。
  2. 提供了抽象原型类,扩展性较好。
  3. 可以使用深拷贝的方式复制一个临时对象。
缺点
  1. 需要为每一个类内部都声明一个克隆方法,当需要对拷贝方法修改时需要修改源码,违背开闭原则。
  2. 实现深拷贝时实现比较复杂,当对象之间存在多重嵌套时要实现深拷贝就需要对每一层对象类支持深拷贝。

原型模式的适用场景

  1. 创建的新对象比较复杂。
  2. 如果需要临时保存对象的状态,而对象的状态变化比较小。
  3. 要实例化的类在运行时指定时。

原型模式案例

// 1. 浅拷贝
@Data
public class Sheep implements Cloneable {
    private String name;
    private int age;
    private String color;
    private String address = "喜羊羊";

    public Sheep friend;

    public Sheep(String name, int age, String color) {
        super();
        this.name = name;
        this.age = age;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";
    }

    @Override
    protected Object clone() {
        Sheep sheep = null;
        try {
            sheep = (Sheep) super.clone();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return sheep;
    }
}

public static void main(String[] args) {
	Sheep sheep = new Sheep("tom", 1, "白色");

	sheep.friend = new Sheep("jack", 2, "黑色");

	Sheep sheep2 = (Sheep)sheep.clone();
	Sheep sheep3 = (Sheep)sheep.clone();

    // 对于浅拷贝,拷贝出来的引用类型成员变量 hashCode 不变
	System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
	System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
}


// 2. 深拷贝
public class DeepProtoType implements Serializable, Cloneable {

    public String name;

    public DeepCloneableTarget deepCloneableTarget;

    public DeepProtoType() {
        super();
    }

    /**
     * 方式1
     *
     * @return Object
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        //这里完成对基本数据类型(属性)和String的克隆
        deep = super.clone();
        //对引用类型的属性,进行单独处理
        DeepProtoType deepProtoType = (DeepProtoType) deep;
        deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();
        return deepProtoType;
    }

    /**
     * 方式2 通过对象的序列化实现 (推荐)
     *
     * @return Object
     */
    public Object deepClone() {
        //创建流对象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            //当前这个对象以对象流的方式输出
            oos.writeObject(this);
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e2) {
                System.out.println(e2.getMessage());
            }
        }
    }

}

public class DeepCloneableTarget implements Serializable, Cloneable {

    private static final long serialVersionUID = 1L;

    private String cloneName;

    private String cloneClass;

    public DeepCloneableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

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

}


public static void main(String[] args) throws Exception {
	DeepProtoType p = new DeepProtoType();
	p.name = "喜羊羊";
	p.deepCloneableTarget = new DeepCloneableTarget("大羊", "小羊");

	DeepProtoType p2 = (DeepProtoType) p.deepClone();

	System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
	System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
}

原型模式在源码中的应用

ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
    ......
}

HashMap

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
    @Override
    public Object clone() {
        HashMap<K,V> result;
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
        result.reinitialize();
        result.putMapEntries(this, false);
        return result;
    }
    ......
}


告别Keil?在Mac上配置STM32CubeIDE + CMSIS-DAP调试器全攻略(含常见报错解决) 本文详细介绍了在Mac平台上配置STM32CubeIDE与CMSIS-DAP调试器的全流程,包括硬件准备、软件安装、工程创建及调试优化。通过实战指南,帮助开发者高效完成STM32开发,解决常见报错问题,提升开发效率。 阅读详情

相关推荐

基于FME—三调篇—尖锐角及小缝隙处理

1 问题分析: 该功能实现在FME较为简单,相对ARCGIS模型构建器以及ARCGIS ENGINE,FME更适合无代码基础的人群。在三调内业数据处理要求中,尖锐角是不允许存在的。本文基于FME实现了对尖锐角的自动查询与消除以及自动处理在消除尖锐角过程中产生的缝隙,并进行了拓扑检查,实现自动化批量处理尖锐角的功能,提高工作效率。 2 总体思路: 2.1 实现功能分析: 1.找出小于指定角度的尖锐角...

qq_33315579的博客 9180

设计模式-原型模式 Prototype Pattern

通常,如果需要快速复制对象并且对象的创建成本较高,或者需要创建多个相似但不完全相同的对象,原型模式是一个更好的选择。原型模式(Prototype Pattern)是一种创建型设计模式,它允许你通过复制现有的对象来创建新的实例,而不是通过新建的方式来构造。使用原型模式可以提高对象创建的效率,降低系统的资源消耗,并有助于实现对象的快速复制和灵活管理。然而,需要注意的是,原型模式可能会增加内存消耗,并且在处理包含引用类型成员的对象时需要特别小心,以避免浅拷贝导致的问题。

wesigj的博客 1699

鼎阳示波器SCPI指令与MD5算法解锁带宽升级实战

本文详细介绍了鼎阳示波器通过SCPI指令与MD5算法实现带宽升级的实战流程。从设备连接、信息获取到Python密钥生成脚本解析,逐步指导用户完成升级操作,并涵盖常见问题排查与功能选件激活指南,帮助用户充分释放设备潜能。

www00的博客 344

23种设计模式之原型模式(Prototype Pattern)

本篇文章将23种设计模式中的单例设计模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

Voltus功耗分析——读入Innovus数据/cpf/spef文件

检查的内容:物理库、时序库、网表、I/Os、tie-high&tie-low pins、电源/地pins。设计数据(LEF/DEF/netlist)、cpf文件、SPEF文件。方法二:定义每个 power/ground net's 电压。4.设计数据检查(design sanity check)方法一:读入.dat数据。方法二:读入def文件。方法一:读入CPF文件。

qq_44347276的博客 3983

保姆级教程:用Docker Compose一键部署WVP-PRO+ZLM+录像服务(含Nginx反代)

本文提供了一套完整的容器化GB28181视频平台部署方案,通过Docker Compose实现WVP-PRO、ZLMediaKit(ZLM)和录像服务的一键式部署。详细介绍了环境准备、架构设计、容器化部署实战以及高级配置优化,帮助用户快速搭建高性能视频监控管理平台,适用于安防行业和物联网设备管理场景。

weixin_30415113的博客 861

设计模式|原型模式(Prototype Pattern)

原型模式(Prototype Pattern)是一种创建型设计模式,其核心思想是通过复制现有对象来创建新对象,而无需显式地指定它们的类。这种模式通常用于当对象的创建成本较高,或者对象初始化过程比较复杂时。

weixin_44435110的博客 1420

【OpenClaw 故障排查完全指南】

OpenClaw 故障排查指南摘要 本指南针对OpenClaw 2026.2.26版本常见问题提供解决方案,适用于Windows/Linux/macOS平台。 核心问题及修复方案: 飞书插件连接失败:删除冲突插件或重装OpenClaw Ollama认证错误:设置环境变量OLLAMA_API_KEY="ollama-local" 配置警告:可安全忽略的安全扫描提示 端口占用:查找并终止占用18789端口的进程 插件重复加载:清理重复插件目录 快速修复: 提供一键修复PowerShell脚本

weixin_37572294的博客 1万+

C++设计模式——原型模式(Prototype Pattern)

C++设计模式——原型模式(Prototype Pattern) 微信公众号:幼儿园的学霸 目录 文章目录C++设计模式——原型模式(Prototype Pattern)目录定义代码示例普通指针方式实现智能指针方式实现总结为什么需要原型模式优缺点 定义 Specify the kinds of Objects to create using a prototypical instance, and create new objects by copying this prototype. 用原型实例指

leonardohaig的博客 1636

VS Code/TRAE集成Cppcheck并启用MISRA规则

本文探讨了嵌入式开发中Cppcheck工具集成与MISRA规则检查的必要性。详细介绍了安装配置步骤:安装VSCode/TRAE、Cppcheck软件、配置插件参数、安装Python环境,并重点说明了MISRA规则文件的设置方法。通过完整的配置流程,实现了嵌入式开发环境下静态检查与安全标准的落地。

SDFangFang2025的博客 1282

YOLOv9改进策略 | Conv篇 | 2024最新ECCV最新大感受野的小波卷积WTConv助力YOLOv9有效涨点

本文给大家带来的改进机制是一种新的卷积层,称为WTConv(小波卷积层),它利用小波变换(WT)来解决卷积神经网络(CNN)在实现大感受野时遇到的过度参数化问题。WTConv的主要目的是通过对输入数据的不同频率带进行处理,使CNN能够更有效地捕捉局部和全局特征,WTConv成功解决了CNN在感受野扩展中的参数膨胀问题,提供了一种更为高效、鲁棒且易于集成的卷积层解决方案,我将其用于二次创新YOLOv9中的RepNCSPELAN4机制可以减少一定的参数量和计算量,达到一个可观的轻量化作用。

Snu77的博客 1543

23种设计模式——原型模式 (Prototype Pattern)详解

本文介绍了23种经典设计模式之——原型模式 (Prototype Pattern)的说明及使用

Meteors.的博客 1001

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【设计模式】原型模式(Prototype Pattern)详解

摘要: 原型模式通过复制已有对象(原型)来创建新对象,避免重复初始化带来的性能开销。核心思想是“拷贝”而非重新构造,适用于创建成本高、对象差异小的场景。Java通过Cloneable接口支持原型模式,但需注意浅拷贝(仅复制对象本身)与深拷贝(复制对象及引用对象)的区别。优点包括提高性能、简化创建过程,缺点在于实现复杂且可能破坏封装性。典型应用包括Spring的prototype作用域、游戏角色复制等。使用时应权衡对象创建成本,避免过度设计。

经天纬地,格物致理 921

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

设计模式之原型模式(Prototype Pattern)

意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。主要解决:在运行期建立和删除原型。何时使用:1、当一个系统应该独立于它的产品创建,构成和表示时。2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。3、为了避免创建一个与产品类层次平行的工厂类层次时。4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。

weixin_42294716的博客 858

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

彻底搞懂设计模式DesignPattern-原型模式

原型模式 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型, 创建新的对象 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节 工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone() 被复制的实例就是我们所称的“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高

Ping 467

设计模式六:原型模式(Prototype Pattern)

原型模式是一种创建对象的设计模式。它允许我们通过复制一个现有对象来创建新的对象,而无需知道其具体实现细节。在使用原型模式时,我们首先创建一个原始对象,然后根据需要复制该对象,以获得新创建的对象。原型模式的主要思想是基于对象的复制。通过使用原型模式,我们可以避免直接实例化对象,从而提高性能和代码灵活性。此外,原型模式还可以用于创建复杂的对象结构,因为它允许我们在创建对象时使用已经存在的对象作为蓝图。

qq_40537587的博客 834

Java设计模式——原型模式【ProtoType Pattern】

Java设计模式、原型模式

scorpio的博客 494

Java设计模式 六 原型模式 (Prototype Pattern)

原型模式是解决对象重复创建问题的强大工具,特别适合那些创建成本高或需要快速生成对象的场景。根据具体需求,可以选择浅拷贝或深拷贝的实现方式。尽管实现上可能会稍复杂,但它提供了灵活性和高效性,是值得掌握的重要设计模式之一。

空 1116

Java 设计模式——原型模式(Prototype Pattern)

Java 设计模式——原型模式(Prototype Pattern) 一.基础概念 1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 2.主要概念 Java中的克隆方法: 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝 二: 具体实现 1.浅...

a158s168的博客 456

设计模式总结之Prototype Pattern(原型模式)

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

cooldragon的专栏 5964

设计模式:原型模式(Prototype Pattern)java版本

摘要 原型模式是一种通过克隆现有对象来创建新实例的设计模式,适用于需要高效生成相似对象的场景。核心思想是利用原型对象的clone()方法快速复制,避免重复初始化开销。文章通过带附件的邮件示例展示了深拷贝实现,并针对在线考试系统的组卷需求,对比了传统方式和原型模式在性能上的差异。典型应用场景包括:对象创建成本高、需要大量相似实例、需保持对象独立性等。实现时需注意区分浅拷贝与深拷贝,可通过序列化或工具类简化深拷贝过程。源码示例见GitHub项目CodeDesignWork。

qq_61875563的博客 881

设计模式-原型模式(Prototype Pattern)

java 设计模式 原型模式

weixin_43438824的博客 889

设计模式——原型模式(Prototype Pattern)

用于创建重复的对象,同时又能保证性能

码鹿的记录 431

设计模式-原型模式(Prototype Pattern)

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库...

shenju2011的博客 294

java设计模式---原型模式(prototype pattern)

java设计模式—原型模式(prototype pattern) 我们在程序开发过程中,都会遇到为一个类创建多个实例的情况,实例的创建开销很大,而且这些实例内部成员往往完全相同或仅有细微的差异,这种情况下如果能通过复制一个已创建的对象实例来重复创建多个相同的对象,这就可以大大减少创建对象的开销,此时就需要使用到原型模式。 1. 定义 原型模式是可以通过一个对象实例确定创建对象的种类,并且通...

渔潭的博客 361

python 设计模式 原型模式_python 设计模式之原型模式 Prototype Pattern

#引入例子1:孙悟空拔下一嘬猴毛,轻轻一吹就会变出好多的孙悟空来。例子2:寄个快递下面是一个邮寄快递的场景:“给我寄个快递。”顾客说。“寄往什么地方?寄给……?”你问。“和上次差不多一样,只是邮寄给另外一个地址,这里是邮寄地址……”顾客一边说一边把写有邮寄地址的纸条给你。“好!”你愉快地答应,因为你保存了用户的以前邮寄信息,只要复制这些数据,然后通过简单的修改就可以快速地创建新的快递数据了。# 原...

weixin_39580041的博客 284
上一篇: 设计模式之工厂方法模式
下一篇: 设计模式之适配器模式
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值