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

一、引言

        在软件工程、软件开发中,创建对象的过程常常涉及复杂的初始化和配置。在某些情况下,直接复制现有对象比从头开始创建新对象更为高效。原型模式(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.mzph.cn/pingmian/58835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【运动的&足球】足球运动员球守门员裁判检测系统源码&数据集全套:改进yolo11-DBBNCSPELAN

改进yolo11-FocalModulation等200全套创新点大全&#xff1a;足球运动员球守门员裁判检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.28 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示…

yocto中一些主要可被改写的函数

以下是 Yocto 中一些主要的可被改写的函数&#xff1a; 1. 源代码获取与准备阶段 do_fetch&#xff1a;从指定位置获取源代码。可用于自定义获取源代码的方式、处理认证或对获取的源进行预处理。do_unpack&#xff1a;解压获取到的源代码包。如果解压格式特殊或解压后需额外处…

React 组件生命周期与 Hooks 简明指南

文章目录 一、类组件的生命周期方法1. 挂载阶段2. 更新阶段3. 卸载阶段 二、函数组件中的 Hooks1. useState2. useEffect3. useContext4. useReducer 结论 好的&#xff0c;我们来详细讲解一下 React 类组件的生命周期方法和函数组件中的钩子&#xff08;hooks&#xff09;。 …

数据库连接池实现

目录 前提&#xff1a;如果我要操作多个表&#xff0c;那么就会产生冗余的JDBC步骤&#xff0c;另一个弊端就是每次都需要数据库连接对象&#xff08;Connection&#xff09;&#xff0c;获取效率低下&#xff0c;每次使用时都需要先进行连接 数据库连接池的特点&#xff1a; …

软件测试基础三(前端知识)

前端基础 1. HTML&#xff08;超文本标记语言&#xff09; 1.1. 基本概念 定义&#xff1a;HTML 是用来描述网页的一种语言&#xff0c;指的是超文本标记语言&#xff08;Hyper Text Markup Language&#xff09;。它不是编程语言&#xff0c;而是一种标记语言&#xff0c;由…

优化用于传感应用的衬底集成波导技术

ANSYS HFSS 是一款功能强大的电磁仿真软件&#xff0c;支持为微流体生物传感器应用设计和分析衬底集成波导 &#xff08;SIW&#xff09; 技术。它为快速设计优化、材料选择、系统集成和虚拟原型制作提供了一个强大的平台。借助 ANSYS HFSS&#xff0c;研究人员和工程师可以高效…

Linux 开机自动挂载硬盘

在日常使用 Linux 系统的过程中&#xff0c;我们可能需要挂载一些机械硬盘或者移动硬盘来存储数据。手动挂载虽然简单&#xff0c;但每次重启后都需要重新操作&#xff0c;未免有些繁琐。那么&#xff0c;如何让硬盘在开机时自动挂载呢&#xff1f;本篇博客将详细介绍如何通过配…

[项目] C++基于多设计模式下的同步异步日志系统

[项目] C基于多设计模式下的同步&异步日志系统 文章目录 [项目] C基于多设计模式下的同步&异步日志系统日志系统1、项目介绍2、开发环境3、核心技术4、日志系统介绍4.1 日志系统的价值4.2 日志系统技术实现4.2.1 同步写日志4.2.2 异步写日志 5、相关技术知识5.1 不定参…

[论文阅读] | 智能体长期记忆

更新记录&#xff1a; 2024.11.2 人大高瓴长期记忆综述 文章目录 人大高瓴长期记忆综述智能体与环境交互记忆的来源/形式/操作来源&#xff1a;(1)当前任务历史信息 (2)其他任务的信息 (3)外部知识形式&#xff1a;如何表达记忆的内容&#xff0c;通过(1)文本 (2)参数(训练到模…

Rust 力扣 - 59. 螺旋矩阵 II

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 使用一个全局变量current记录当前遍历到的元素的值 我们只需要一圈一圈的从外向内遍历矩阵&#xff0c;每一圈遍历顺序为上边、右边、下边、左边&#xff0c;每遍历完一个元素后current 我们需要注意的是如果上…

AppInventor2能否用网络摄像头画面作为屏幕的背景?

// 视频是否可以作为背景&#xff1f; // 有会员提问&#xff1a;能否用网络摄像头的实时画面作为屏幕的背景&#xff1f;就跟这个一样背景全覆盖&#xff1a; 摄像头画面是一个在线的网站链接视频流。 // 原先思路 // 1、目前原生组件无法直接实现这个功能&#xff0c;屏幕…

国产操作系统卖疯了!最营收7.84亿,最低1.5亿

最近看各种报道&#xff0c;似乎国产化有提速的绩效&#xff0c;那么既然如此&#xff0c;各个国产操作系统厂商是不是都起飞了呢&#xff1f; 周末闲暇之余&#xff0c;我们来看看各家的营收表现。 银河麒麟2024年1-9月一共卖了多少钱&#xff1f; 前几天中国软件发布了202…

CDN加速实战:使用七牛云CDN加速阿里云OSS资源访问

今天是双11搞活动,在阿里云1元注册了个域名,想着在学CDN,想使用CDN做个加速项目,但是阿里的要收费,上网查了下七牛云的不收费,想着将七牛云的CDN结合阿里的DNS做个访问加速,刚好看到了阿里的一个文章,照着改了改,实践成功了。 阿里文章:使用CDN加速OSS资源访问_对象…

嵌入式学习——IIC协议

IIC&#xff08;Inter-Integrated Circuit&#xff09;是一种串行通信协议&#xff0c;由飞利浦公司于1980年代提出。它允许多个从设备通过两条线&#xff08;SDA和SCL&#xff09;与一个或多个主设备进行通信。IIC协议是多主、多从的&#xff0c;适合在短距离内的设备间通信。…

qt QStatusBar详解

1、概述 QStatusBar是Qt框架提供的一个小部件&#xff0c;用于在应用程序窗口底部显示状态信息。它可以显示一些固定的文本和图标&#xff0c;并且可以通过API动态更新显示内容。QStatusBar通常是一个水平的窗口部件&#xff0c;能够显示多行文本内容&#xff0c;非常适合用于…

大型语言模型的运行成本分析

大型语言模型 (LLM) 一直处于生成式 AI 革命的前沿&#xff0c;尤其是自 ChatGPT 出现以来。然而&#xff0c;它们的全部潜力尚未得到释放&#xff0c;而一个重大障碍是成本。将 LLM 纳入应用程序的费用范围从按需用例的几美分到在云环境中托管单个 LLM 实例的每月 20,000 美元…

Matlab高光谱遥感

原文链接&#xff1a;Matlab高光谱遥感https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247623643&idx5&sne4557ed43728f851140b100f42286988&chksmfa8da23ccdfa2b2a4d795bf4087f672faaa7082d1f52e046616ab7bf196a6eef89ea553d06b1&token1392391660&…

OPENAI官方prompt文档解析

官方文档地址:https://platform.openai.com/docs/guides/gpt-best-practices 文档中文版来源:OpenAI 官方提示工程指南 [译] | 宝玉的分享 (baoyu.io) 1.写清楚说明 如果prompt给的范围十分模糊或是过于宽泛,那么GPT就会开始猜测您想要的内容,从而导致生成的结果偏离预期. …

共模噪声和差模噪声

电源芯片加上负载和不加负载输出的纹波不一样&#xff0c;不加负载的情况下纹波比较小。 可以测量出DCDC电源的输出电压纹波为100Khz&#xff0c;刚好对应电源芯片的开关频率。可以看到纹波上面有一部分的小噪声&#xff0c;放大后用示波器观察频率为几Mhz。 对付上面的频率比…

DevOps赋能:优化业务价值流的实战策略与路径(上)

上篇&#xff1a;价值流引领与可视化体系构建 一、前言 在快速迭代的软件项目和产品开发生态中&#xff0c;我们始终围绕两个核心目标&#xff1a;一是确保每一项工作都能为客户创造实际价值&#xff0c;这是产品团队的核心使命&#xff1b;二是确保这些有价值的工作能够高效…