【再谈设计模式】原型模式~复制的魔法师

一、引言

        在软件工程、软件开发中,创建对象的过程常常涉及复杂的初始化和配置。在某些情况下,直接复制现有对象比从头开始创建新对象更为高效。原型模式(Prototype Pattern)是一种创建型设计模式,允许我们通过复制现有对象来创建新对象,而不是通过构造函数。这种模式在需要频繁创建相似对象的场景中非常有用。

二、定义与描述

        原型模式定义了一种用于创建对象的接口,使得通过复制现有对象来生成新对象成为可能。它的核心思想是将对象的创建过程与具体类的实现分离,从而提高了系统的灵活性和可扩展性。

主要组成部分

  • 原型接口(Prototype):声明一个克隆自身的接口。
  • 具体原型(ConcretePrototype):实现克隆方法以返回自身的副本。
  • 客户端(Client):使用原型对象来创建新的对象。

三、抽象背景

        在许多应用程序中,尤其是图形界面、游戏开发和配置管理中,创建对象的过程可能会涉及复杂的初始化逻辑。传统的构造方法可能会导致代码重复和性能开销。原型模式通过提供一个简单的克隆接口,简化了对象的创建过程,并避免了不必要的重复代码。

四、适用场景与现实问题解决

适用场景

  • 需要大量相似对象:在需要创建大量相似对象时,使用原型模式可以减少内存消耗和提高性能。
  • 对象创建成本高:当创建对象的成本较高(例如,涉及数据库查询或复杂的计算)时,使用原型模式可以通过复制现有对象来降低成本。
  • 动态配置对象:在运行时需要动态配置对象的属性时,原型模式可以提供灵活性。

现实问题解决

        假设我们正在开发一个图形编辑器,需要创建多个相似的图形对象(如圆形、矩形等)。每个图形对象都具有相似的属性(如颜色、大小等),但可能有不同的值。使用原型模式,我们可以通过复制现有图形对象来快速创建新对象,而不必每次都重新初始化所有属性。

原型模式的现实生活例子:手机定制与复制

        想象一下,一位手机制造商,专注于生产个性化的手机。顾客可以根据自己的喜好选择手机的颜色、内存、存储和其他配置。为了提高生产效率,决定使用原型模式来快速生成顾客所需的手机。让我们来看看这个过程是如何运作的。

场景设定

        在工厂中,有一款最新款的手机模型,称为“超级手机X”。这款手机有多种配置和颜色,但每次顾客下单时,不想从头开始制作一部新手机。于是,决定利用原型模式。

原型模式的工作原理
  • 原型(Prototype)

    • “超级手机X”就是原型。它包含了手机的基本配置,比如处理器、内存、摄像头等信息。这个原型可以被克隆,作为其他手机的基础。
  • 克隆(Clone)

    • 当顾客选择了特定的配置(比如红色外壳、256GB存储、8GB内存)时,并不需要从头开始组装一部新手机。相反,只需调用“超级手机X”的克隆方法,快速生成一部新手机。
  • 个性化(Personalization)

    • 在克隆的过程中,可以根据顾客的选择对手机进行个性化调整。例如,将外壳颜色改为红色,内存升级到8GB,存储升级到256GB。这些调整就像是在原型基础上进行的小修改,确保每位顾客都能得到他们理想中的手机。

        通过使用原型模式,生产效率大大提高。顾客下单后,可以迅速生成他们所需的手机,而不需要每次都进行复杂的组装和配置。这样,不仅缩短了交货时间,还提升了顾客的满意度。

        如果没有原型模式,可能要在工厂里忙得不可开交。每当顾客下单,就得重新找出所有零件,像拼图一样把手机组装起来。结果可能是:一边找零件,一边还要应对顾客的催促,最后出来的手机可能连颜色都搞错了,顾客想要红色的,结果却拿到了一部绿色的。

        而有了原型模式,就像拥有了一台“魔法克隆机”,每次只需轻松一按,手机就能迅速出炉,顾客们都满意得像小孩一样开心。

        所以,原型模式就像这个神奇的手机生产流程,在制造个性化产品时,避免了重复的劳动,轻松应对各种需求!

五、初衷与问题解决

        原型模式的初衷是解决对象创建过程中的复杂性和性能问题。通过允许对象自身负责克隆操作,原型模式使得对象的创建更加灵活和高效。它特别适用于以下几种情况:

  • 避免复杂的构造逻辑:在某些情况下,构造函数可能需要接收大量参数,使用原型模式可以简化对象的创建过程。
  • 减少内存开销:通过共享相似对象的状态,原型模式可以减少内存的使用。

六、编码示例

        原型模式在 Java、Go、C++ 和 Python 中的实现示例。

Java 实现

// 原型接口
interface Prototype {Prototype clone();
}// 具体原型
class ConcretePrototype implements Prototype {private String name;public ConcretePrototype(String name) {this.name = name;}public String getName() {return name;}@Overridepublic Prototype clone() {return new ConcretePrototype(this.name);}
}// 客户端
public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("原型");ConcretePrototype clone = (ConcretePrototype) prototype.clone();System.out.println("克隆对象名称: " + clone.getName());}
}

Go 实现

package mainimport ("fmt"
)// 原型接口
type Prototype interface {Clone() Prototype
}// 具体原型
type ConcretePrototype struct {Name string
}func (p *ConcretePrototype) Clone() Prototype {return &ConcretePrototype{Name: p.Name}
}func main() {prototype := &ConcretePrototype{Name: "原型"}clone := prototype.Clone()fmt.Println("克隆对象名称:", clone.(*ConcretePrototype).Name)
}

C++ 实现

#include <iostream>
#include <memory>// 原型接口
class Prototype {
public:virtual std::unique_ptr<Prototype> clone() const = 0;virtual std::string getName() const = 0;virtual ~Prototype() = default;
};// 具体原型
class ConcretePrototype : public Prototype {
private:std::string name;public:ConcretePrototype(const std::string& name) : name(name) {}std::unique_ptr<Prototype> clone() const override {return std::make_unique<ConcretePrototype>(*this);}std::string getName() const override {return name;}
};// 客户端
int main() {ConcretePrototype prototype("原型");std::unique_ptr<Prototype> clone = prototype.clone();std::cout << "克隆对象名称: " << clone->getName() << std::endl;return 0;
}

Python 实现

import copy# 原型接口
class Prototype:def clone(self):pass# 具体原型
class ConcretePrototype(Prototype):def __init__(self, name):self.name = namedef clone(self):return copy.deepcopy(self)# 客户端
if __name__ == "__main__":prototype = ConcretePrototype("原型")clone = prototype.clone()print("克隆对象名称:", clone.name)

七、原型模式的优缺点

优点

  • 简化对象创建:通过克隆现有对象,可以避免复杂的构造逻辑。
  • 提高性能:在需要频繁创建相似对象的场景中,使用原型模式可以提高性能。
  • 灵活性:可以在运行时动态改变对象的状态。

缺点

  • 实现复杂性:需要实现克隆方法,可能会增加代码的复杂性。
  • 深度复制问题:如果对象内部包含引用类型的属性,可能需要实现深度复制,以避免共享状态带来的问题。
  • 克隆限制:某些对象可能无法被克隆(例如,具有不可变状态的对象)。

八、原型模式的升级版

原型模式的升级版通常涉及更复杂的克隆机制,例如:

  • 深度克隆与浅克隆:根据需求实现深度克隆和浅克隆,以处理复杂对象的状态。
  • 克隆工厂:使用工厂模式结合原型模式,创建一个专门的克隆工厂类,管理不同类型的原型对象。
  • 配置文件:在一些场景中,可以将对象的状态存储在配置文件中,通过读取配置文件来创建对象,结合原型模式可以实现更灵活的对象创建。

        原型模式是一个强大的设计模式,适用于需要频繁创建相似对象的场景。通过理解原型模式的基本概念、适用场景、优缺点以及实现方式,开发者可以在实际项目中灵活运用这一模式,提高代码的可维护性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/5682.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

技术分享 —— JMeter接口与性能测试实战!

前言 在软件开发和运维过程中&#xff0c;接口性能测试是一项至关重要的工作。JMeter作为一款开源的Java应用&#xff0c;被广泛用于进行各种性能测试&#xff0c;包括接口性能测试。本文将详细介绍如何使用JMeter进行接口性能测试的过程和步骤。 JMeter是Apache组织开发的基…

Data+AI━━数据安全的警钟:智能化分类分级治理

DataAI━━数据安全的警钟&#xff1a;智能化分类分级治理 前言数据的分类体系数据分级与智能化实践深度案例解析与未来展望 前言 OpenAI数据泄露事件让数据安全再次成为科技圈的热门话题。2024年3月,一名研究员发现OpenAI的API存在安全漏洞,导致部分用户的对话记录泄露。 这一…

【K8S问题系列】Kubernetes Pod节点CrashLoopBackOff 状态【已解决】

在 Kubernetes 中&#xff0c;Pod 的状态为 CrashLoopBackOff 表示某个容器在启动后崩溃&#xff0c;Kubernetes 尝试重启该容器&#xff0c;但由于持续崩溃&#xff0c;重启的间隔时间逐渐增加。下面将详细介绍 CrashLoopBackOff 状态的原因、解决方案及相关命令的输出解释。 …

图像信号处理器(ISP,Image Signal Processor)详解

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 图像信号处理器&#xff08;ISP&#xff0c;Image Signal Processor&#xff09; 是专门用于处理图像信号的硬件或处理单元&#xff0c;广泛应用于图像传感器&#xff08;如 CMOS 或 CCD 传感器&a…

u盘怎么重装电脑系统_u盘重装电脑系统步骤和详细教程【新手宝典】

u盘怎么重装电脑系统&#xff1f;一个u盘怎么重装电脑系统呢&#xff0c;需要将u盘制作成u盘启动盘pe&#xff0c;然后通过U盘启动盘进入pe进行安装系统&#xff0c;下面小编就教大家u盘重装电脑系统步骤和详细教程。 u盘启动是什么意思&#xff1f; U盘启动盘是一种具有特殊功…

SpringBoot健身房管理:技术与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一)

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一) Sigrity Power SI使用3D-EM Inductance Extraction模式可以进行电感的提取,以下图为例 2D 视图 <

Fsm serialdata

现在您有了一个有限状态机&#xff0c;可以识别串行比特流中何时正确接收字节&#xff0c;添加一个数据路径&#xff0c;输出正确接收的数据字节。当done为1时&#xff0c;out_byte必须有效&#xff0c;否则为not。 请注意&#xff0c;串行协议首先发送最低有效位。 此题&#…

【GESP】C++一级真题练习(202309)luogu-B3863,买文具

GESP一级真题练习。为2023年9月一级认证真题。属于数值计算条件判断的问题。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-luogu-b3863/ 【GESP】C一级真题练习(202309)luogu-B3863&#xff0c;买文具 | OneCoderGESP一级真题练习。为2023年9月一级认证真题。属…

《Python游戏编程入门》注-第5章4

2.3 随机改变颜色 从图1中可以看出,当完全显示了一个大圆之后,会改变颜色继续显示该大圆。也就是当圆心角angle的值大于等于360度时,随机改变颜色,代码如图6所示。 图6 随机改变颜色的代码 其中,第18行代码判断是否完全显示了一个大圆,如果是,圆心角的角度设置为0,第…

健康生活,注重养生

在快节奏的现代生活中&#xff0c;健康养生已成为我们不可忽视的重要课题。它不仅仅关乎身体的强健&#xff0c;更涉及到心灵的平和与愉悦。以下是一些实用的健康养生建议&#xff0c;帮助我们在日常生活中&#xff0c;以自然和谐的方式&#xff0c;滋养身心&#xff0c;享受生…

气膜体育馆:高效便捷的现代运动新选择—轻空间

随着城市发展和人们健康意识的提高&#xff0c;体育场馆的需求日益增加。然而&#xff0c;传统体育馆的建设周期长、成本高和多功能性有限&#xff0c;往往无法满足快速发展的城市需求。那么&#xff0c;为什么选择气膜体育馆作为您的场馆建设方案呢&#xff1f;今天&#xff0…

SSLHandshakeException错误解决方案

1、错误提示 调用Http工具报如下异常信息&#xff1a; cn.hutool.core.io.IORuntimeException: SSLHandshakeException: Received fatal alert: handshake_failure2、查询问题 一开始我以为是代码bug&#xff0c;网络bug甚至是配置环境未生效&#xff0c;找了一大圈&#xf…

第十八周:机器学习

目录 摘要 abstract 一、BERT 1、应用场景 任务一&#xff1a;单句子分类任务 任务二&#xff1a;单句子标注任务 任务三&#xff1a;句子对分类任务 任务四&#xff1a;问答系统 2、pre-train model 3、fine tune微调 input&output how to fine tune 二、…

从0开始搭建一个生产级SpringBoot2.0.X项目(十二)SpringBoot接口SpringSecurity JWT鉴权

前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 SpringBoot接口权限控制 SpringSecurity 接口使用 Bearer token类型 JWT 鉴权 一、pom文件新增依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

LightRAG成功跑通:Ollama+Qwen2.5+bge-large-zh-v1.5

目录 LightRAG跑通1.安装环境2.示例跑通&#xff1a;&#xff08;1&#xff09;准备样例数据&#xff08;2&#xff09;源码修改&#xff08;3&#xff09;中文示例跑通 4.Neo4j可视化图谱5.问题解决&#xff1a;跑通后感受&#xff1a; LightRAG跑通 继GraphRAG之后&#xff…

qt QMovie详解

1、概述 QMovie 是 Qt 框架中用于处理动画文件的类。它支持多种动画格式&#xff0c;包括 GIF 和一些常见的视频格式&#xff08;尽管对视频格式的支持依赖于底层平台&#xff09;。QMovie 类主要用于在 QLabel 或 QGraphicsView 等控件中显示动画。通过加载动画文件&#xff…

二叉树的练习题(上)

1. 前序遍历 题目解析: 题目: . - 力扣&#xff08;LeetCode&#xff09; 解题步骤: 题目给定的返回值是一个链表,也就是我们每一次前序遍历都要把遍历结果保存到顺序表里面进行返回. 前序遍历: 根结点 -> 左子树 -> 右子树 我们的遍历过程如图 就相当于所有的结点 …

LabVIEW高效数据采集与信号处理系统

开发一个基于LabVIEW软件的数据采集与信号处理系统&#xff0c;实现高效的数据采集和信号处理。系统通过优化数据流处理过程和直观的图形化界面&#xff0c;提高了操作效率和数据准确性&#xff0c;特别适合工业和科研应用。 ​ 项目背景 在现代工业和科研领域&#xff0c;数…

ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源 或者超时失效

数据治理过程中&#xff0c;有字段长度不够&#xff0c;扩展字段&#xff0c;报&#xff1a;ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源 或者超时失效 ALTER TABLE LAPD_RSJ_CXJMYLBXCBXX MODIFY HKXZ VARCHAR2(10);错误表示当前会话在试图访问的资源&#xff08;通常…