设计模式-原型模式详解

文章目录

  • 前言
  • 理论基础
    • 1. 原型模式定义
    • 2. 原型模式角色
    • 3. 原型模式工作过程
    • 4. 原型模式的优缺点
  • 实战应用
    • 1. 原型模式适用场景
    • 2. 原型模式实现步骤
    • 3. 原型模式与单例模式的区别
  • 原型模式的变体
    • 1. 带有原型管理器的原型模式
    • 2. 懒汉式单例模式的原型模式实现
    • 3. 细粒度原型模式
  • 总结

前言

  • 简介设计模式
  • 设计模式是在软件开发中常见问题的解决方案,它们是经过实践和经验总结出来的可重用的设计思想和解决方案。设计模式通过提供通用的架构、原则和指导,帮助开发人员更有效地编写高质量的代码。
    设计模式分为三个主要类别:
  1. 创建型模式:关注对象的创建过程,包括如何实例化对象,隐藏对象的创建细节以及对象的复制和克隆。
  2. 结构型模式:关注对象和类的组合方式,以实现更大结构的目标,例如类之间的关系。
  3. 行为型模式:关注类和对象间的交互和通信方式,以实现更好的协作和控制。
  • 原型模式简介
    原型模式是创建型模式的一种,它关注对象的复制和克隆。在某些情况下,通过传统的实例化方式创建新对象可能会非常昂贵或复杂。这时,原型模式提供了一种替代方法,通过克隆已有的对象来创建新对象,从而避免了昂贵的初始化过程。

原型模式通过使用克隆方法来生成新对象,可以节省资源和时间,并提高对象创建的效率。它适用于需要创建大量相似对象的场景,同时也具有良好的扩展性,可以根据需要通过继承和重写克隆方法来实现自定义的克隆逻辑。

总结起来,原型模式是一种通过克隆现有对象来创建新对象的设计模式。它提供了一种灵活、高效的对象创建方式,可以在某些场景下显著提高代码的复用性和可维护性。
在这里插入图片描述

理论基础

1. 原型模式定义

原型模式是一种创建型设计模式,它允许通过克隆现有对象来创建新对象,而无需依赖于传统的实例化过程。该模式通过复制现有对象的属性和状态,创建新的独立对象,并且可以根据需要修改其特定属性。

在原型模式中,我们定义一个抽象原型类,其中包含一个用于克隆对象的抽象方法。具体原型类则继承自抽象原型类,并实现了克隆方法,以便返回自身的克隆副本。客户端代码使用具体原型类的实例,并调用其克隆方法来创建新的对象。

原型模式的关键思想是通过已存在的对象来创建新的对象,而不是从头开始进行全新的实例化过程。通过克隆现有对象,可以避免重复的初始化工作和资源消耗,提高对象创建的效率。同时,原型模式也使得对象的创建更加灵活,可以根据需要进行修改和定制。

2. 原型模式角色

  • 抽象原型类
  • 具体原型类
  • 客户端

3. 原型模式工作过程

4. 原型模式的优缺点

实战应用

1. 原型模式适用场景

  • 对象初始化过程耗时较多
  • 类初始化需要消耗很多资源
  • 通过new的方式创建对象比较复杂
  • 需要避免使用类的子类来进行初始化配置

2. 原型模式实现步骤

  • 创建抽象原型类
  • 创建具体原型类
  • 创建客户端类

3. 原型模式与单例模式的区别

原型模式的变体

1. 带有原型管理器的原型模式

  • 带有原型管理器的原型模式:
    带有原型管理器的原型模式是对原型模式的扩展,它引入了一个原型管理器(Prototype Manager)来集中管理原型对象。原型管理器充当一个注册表,用于存储和获取各种原型对象。

这种变体的原型模式可以更方便地创建和管理多个不同类型的原型对象。客户端可以通过原型管理器获取所需的原型对象,而不需要自己显式地调用克隆方法。原型管理器可以在内部维护一个原型对象的集合,并根据需要进行复制和返回。

  • 带有原型管理器的原型模式代码实现:
import java.util.HashMap;
import java.util.Map;// 原型接口
interface Prototype {Prototype clone();
}// 具体原型类 A
class ConcretePrototypeA implements Prototype {private String name;public ConcretePrototypeA(String name) {this.name = name;}public String getName() {return name;}@Overridepublic Prototype clone() {return new ConcretePrototypeA(this.name);}
}// 具体原型类 B
class ConcretePrototypeB implements Prototype {private int number;public ConcretePrototypeB(int number) {this.number = number;}public int getNumber() {return number;}@Overridepublic Prototype clone() {return new ConcretePrototypeB(this.number);}
}// 原型管理器
class PrototypeManager {private Map<String, Prototype> prototypes;public PrototypeManager() {prototypes = new HashMap<>();}public void registerPrototype(String key, Prototype prototype) {prototypes.put(key, prototype);}public Prototype getPrototype(String key) {Prototype prototype = prototypes.get(key);if (prototype != null) {return prototype.clone();}return null;}
}// 客户端
public class Main {public static void main(String[] args) {PrototypeManager manager = new PrototypeManager();manager.registerPrototype("A", new ConcretePrototypeA("Prototype A"));manager.registerPrototype("B", new ConcretePrototypeB(10));Prototype prototypeA = manager.getPrototype("A");if (prototypeA != null) {System.out.println("Clone A: " + ((ConcretePrototypeA) prototypeA).getName());}Prototype prototypeB = manager.getPrototype("B");if (prototypeB != null) {System.out.println("Clone B: " + ((ConcretePrototypeB) prototypeB).getNumber());}}
}

2. 懒汉式单例模式的原型模式实现

  • 懒汉式单例模式的原型模式:
    懒汉式单例模式是一种常见的单例模式实现方式,它延迟实例化单例对象,直到第一次使用时才创建。将懒汉式单例模式与原型模式结合起来,可以实现一种延迟加载并复用实例的模式。

在这种变体的原型模式中,单例对象充当原型对象,当客户端第一次请求获取实例时,会通过克隆来获得对象的副本,并将其作为单例对象返回。之后,每次请求都将返回这个已存在的副本,避免了重复的创建和初始化过程。

这种实现方式结合了懒加载和对象的复用,可以在需要的时候动态创建新对象并缓存起来,提高了系统的性能和资源利用率。

  • 懒汉式单例模式的原型模式代码实现:
// 单例类
class Singleton {private static Singleton instance;// 私有构造函数private Singleton() {System.out.println("Singleton instance created.");}// 获取单例对象public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}// 克隆方法@Overrideprotected Object clone() throws CloneNotSupportedException {throw new CloneNotSupportedException("Cannot clone a singleton object.");}
}// 客户端
public class Main {public static void main(String[] args) {Singleton singleton1 = Singleton.getInstance();Singleton singleton2 = Singleton.getInstance();System.out.println("Singleton 1: " + singleton1);System.out.println("Singleton 2: " + singleton2);// 尝试克隆单例对象try {Singleton clone = (Singleton) singleton1.clone();System.out.println("Clone: " + clone);} catch (CloneNotSupportedException e) {System.out.println(e.getMessage());}}
}

3. 细粒度原型模式

  • 细粒度原型模式:
    细粒度原型模式是指将一个复杂对象拆分成多个部分,并为每个部分创建对应的原型对象。这样,在需要使用某个部分时,只需要克隆该部分的原型对象即可,而不需要克隆整个复杂对象。

细粒度原型模式可以提高系统的灵活性和效率。它允许客户端选择需要的部分进行克隆,而不需要克隆整个对象。同时,当某个部分发生变化时,只需要修改对应的原型对象,而不需要重新创建整个对象。

这种模式适用于那些由多个组件或模块组成的复杂对象。通过细粒度的原型对象,可以更加灵活地构建和修改复杂对象的组成部分,减少了代码的重复和耦合度。

  • 细粒度原型模式代码
// 原型接口
interface Prototype {Prototype clone();
}// 具体原型类 A
class ConcretePrototypeA implements Prototype {private String name;public ConcretePrototypeA(String name) {this.name = name;}public String getName() {return name;}@Overridepublic Prototype clone() {return new ConcretePrototypeA(this.name);}
}// 具体原型类 B
class ConcretePrototypeB implements Prototype {private int number;public ConcretePrototypeB(int number) {this.number = number;}public int getNumber() {return number;}@Overridepublic Prototype clone() {return new ConcretePrototypeB(this.number);}
}// 客户端
public class Main {public static void main(String[] args) {Prototype prototypeA = new ConcretePrototypeA("Prototype A");Prototype cloneA = prototypeA.clone();if (cloneA instanceof ConcretePrototypeA) {System.out.println("Clone A: " + ((ConcretePrototypeA) cloneA).getName());}Prototype prototypeB = new ConcretePrototypeB(10);Prototype cloneB = prototypeB.clone();if (cloneB instanceof ConcretePrototypeB) {System.out.println("Clone B: " + ((ConcretePrototypeB) cloneB).getNumber());}}
}

总结

  • 原型模式使用总结
  • 原型模式对于软件开发的重要性
// 抽象原型类
abstract class Prototype implements Cloneable {public abstract Prototype clone();
}// 具体原型类
class ConcretePrototype extends Prototype {@Overridepublic 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();ConcretePrototype clone = (ConcretePrototype) prototype.clone();// 进行操作}
}

以上代码展示了原型模式的简单实现,其中抽象原型类定义了一个抽象方法clone,在具体原型类中实现了这个方法,并通过调用super.clone()方法进行对象的克隆。在客户端中,可以创建一个原型对象并进行克隆,从而得到一个新的对象进行操作。

原型模式适用于需要创建大量相似对象的场景,通过克隆已有对象来提高效率。它简化了对象的创建过程,减少了重复的初始化操作。同时,原型模式也具有良好的可扩展性,可以通过继承和重写clone方法来实现自定义的克隆逻辑。

总的来说,原型模式是一种简单而实用的设计模式,在软件开发中具有广泛的应用价值。通过合理地运用原型模式,可以提高代码的复用性、可维护性和灵活性,从而提高软件开发的效率和质量。

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

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

相关文章

无涯教程-JavaScript - RANK函数

RANK函数取代了Excel 2010中的RANK.EQ函数。 描述 该函数返回数字列表中数字的等级。数字的等级是其相对于列表中其他值的大小。 如果对列表进行排序,则数字的排名将是其位置。 语法 RANK (number,ref,[order])争论 Argument描述Required/OptionalNumberThe number whose…

Elasticsearch 对比传统数据库:深入挖掘 Elasticsearch 的优势

当你为项目选择数据库或搜索引擎时&#xff0c;了解每个选项的细微差别至关重要。 今天&#xff0c;我们将深入探讨 Elasticsearch 的优势&#xff0c;并探讨它与传统 SQL 和 NoSQL 数据库的比较。 1. Elasticsearch简介 Elasticsearch 以强大的 Apache Lucene 库为基础&#…

山西电力市场日前价格预测【2023-09-04】

日前价格预测 预测明日&#xff08;2023-09-04&#xff09;山西电力市场全天平均日前电价为305.57元/MWh。其中&#xff0c;最高日前电价为349.83元/MWh&#xff0c;预计出现在19: 15。最低日前电价为226.28元/MWh&#xff0c;预计出现在13: 30。 价差方向预测 1&#xff1a; 实…

11.Redis的慢操作之rehash

Redis为什么快 它接收到一个键值对操作后&#xff0c;能以微秒级别的速度找到数据&#xff0c;并快速完成操作。 数据库这么多&#xff0c;为啥 Redis 能有这么突出的表现呢&#xff1f; 内存数据结构 一方面&#xff0c;这是因为它是内存数据库&#xff0c;所有操作都在内存上…

MATLAB中编译器中的变量联系到Simulink

MATLAB中编译器中的变量联系到Simulink 现在编译器中创建变量&#xff0c;进行编译&#xff0c;使其生成在工作区。 然后在Simulink中国使用变量即可。

如何使用CSS实现一个带有动画效果的折叠面板(Accordion)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 带有动画效果的折叠面板&#xff08;Accordion&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个…

服务器监控可视化

IT监控可视化是一种将IT监控数据以图形化的方式呈现给用户的技术&#xff0c;可以帮助用户更直观、更易懂地了解IT系统的运行状况。服务器监控可视化是其中的一个重要应用场景&#xff0c;可以将服务器的各种性能指标以图表、仪表盘等形式展示&#xff0c;以便管理员更好地了解…

质谱技术对蛋白质进行鉴定

参考B站教学视频: 质谱如何鉴定蛋白质_哔哩哔哩_bilibili 针对该视频&#xff0c;别人的 笔记 质谱是一台体重秤&#xff0c;称的不是人&#xff0c;而是分子、原子的体重 不同分子有不同分子量是质谱仪工作的底层逻辑 图片来自&#xff1a;【蛋白组】蛋白质组定量技术的原理和…

Ubuntu18.04安装cuDNN

注册账号 https://developer.nvidia.com/rdp/cudnn-archive 该网站下载安装包需要先进行注册。登录成功后&#xff0c;找到与CUDA对应的版本。 选择Linux版本进行下载。 下载后的格式为.tar.xz 解压 tar xvJf cudnn-linux-x86_64-8.9.3.28_cuda12-archive.tar.xz配置环境 su…

一个集成的BurpSuite漏洞探测插件1.2

4、DNSLog查询漏报 注&#xff1a;扫描结束后才会在BurpSuite的Target、Dashboard模块显示高危漏洞&#xff0c;进程扫描中无法进行同步&#xff0c;但可以在插件中查看&#xff08;涉及到DoPassive方法问题&#xff09;。

使用自动模型

本文通过文本分类任务演示了HuggingFace自动模型使用方法&#xff0c;既不需要手动计算loss&#xff0c;也不需要手动定义下游任务模型&#xff0c;通过阅读自动模型实现源码&#xff0c;提高NLP建模能力。 一.任务和数据集介绍 1.任务介绍 前面章节通过手动方式定义下游任务模…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,动态数组(重点推荐))七(129)

需求&#xff1a;前端根据后端的返回数据&#xff1a;画统计图&#xff1b; 说明&#xff1a; 1.X轴为地域&#xff0c;Y轴为地域出现的次数&#xff1b; 2. 动态展示&#xff08;有地域展示&#xff0c;没有不展示&#xff0c;且高低排序&#xff09; Demo案例&#xff1a; …

Python 分析HTTP的可靠性

在这篇文章中&#xff0c;我们将介绍如何使用 Python 来分析代理服务提供商的可靠性。代理服务在许多场景中都非常有用&#xff0c;例如突破地理限制、保护隐私和提高网络安全性。然而&#xff0c;并非所有的代理服务提供商都是可靠的。因此&#xff0c;我们将使用 Python 来测…

leetcode 941. 有效的山脉数组

2023.9.2 可以用双指针法来做&#xff0c;left指向数组起点&#xff0c;right指向数组终点&#xff0c;left满足条件则左移&#xff0c;right满足条件则右移&#xff0c;最终两指针重合则返回true。 期间任一条件不满足则返回false。 代码如下&#xff1a; class Solution { p…

【80天学习完《深入理解计算机系统》】第十二天3.6数组和结构体

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

OJ练习第159题——消灭怪物的最大数量

消灭怪物的最大数量 力扣链接&#xff1a;1921. 消灭怪物的最大数量 题目描述 你正在玩一款电子游戏&#xff0c;在游戏中你需要保护城市免受怪物侵袭。给你一个 下标从 0 开始 且长度为 n 的整数数组 dist &#xff0c;其中 dist[i] 是第 i 个怪物与城市的 初始距离&#…

筑牢数据隐私安全底线,ADSCOPE通过ISO隐私信息管理体系认证!

数字时代&#xff0c;信息安全尤其是数据隐私信息保护已经成为社会共识。近日&#xff0c;ADSCOPE&#xff08;上海倍孜网络技术有限公司&#xff09;已通过相关组织机构评审&#xff0c;符合ISO/IEC 27701&#xff1a;2019标准&#xff0c;获得隐私信息管理体系认证证书&#…

Jmeter(三十一):制造大批量的用户数据数据

需求&#xff1a;因测试需要&#xff0c;要造100w用户数据&#xff0c;通过用户名、手机号、密码可新增用户&#xff0c;其中用户名和电话号码要求100w用户不能重复 要点&#xff1a; 1、通过Bean shell Sampler实现用户名和手机号的足够随机。 符合我们常用规则的手机号&#…

torch.bmm功能解读

bmm 是 batched matrix multiple 的简写&#xff0c;即批量矩阵乘法&#xff0c;矩阵是二维的&#xff0c;加上batch一个维度&#xff0c;因此该函数的输入必须是两个三维的 tensor&#xff0c;三个维度代表的含义分别是&#xff1a;&#xff08;批量&#xff0c;行&#xff0c…

JVM学习(五)--方法区

概念&#xff1a; 方法区就是存和类相关的东西&#xff0c;成员方法&#xff0c;方法参数&#xff0c;成员变量&#xff0c;构造方法&#xff0c;类加载器等&#xff0c;逻辑上存在于堆中&#xff0c;但是不同的虚拟机对它的实现不同&#xff0c;oracle的hotsport vm在1.6的时…