设计模式-生成器模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 生成器模式和工厂模式的区别
    • 代码示例
      • Java实现生成器模式
      • Python实现生成器模式
    • 生成器模式在spring中的应用


模式介绍

生成器模式是一种创建型模式,它的主要目的是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

生成器模式的使用场景包括:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时;当构造过程必须允许被构造的对象有不同的表示时。

生成器模式的主要优点包括:建造者独立,易扩展;便于控制细节风险。缺点则在于:产品必须有共同点,范围有限制;如内部变化复杂,会有很多的建造类。

在这里插入图片描述

模式特点

生成器模式的主要特点有以下几点:

  1. 可变性:生成器模式允许用户变化它建造产品的内部表达形式,同时隐藏了产品怎样被装配的细节。
  2. 模块化:每个具体的生成器都独立于程序的其他生成器,这改善了程序的模块化,并使添加其他生成器变得简单。
  3. 控制性:由于每个生成器根据数据逐步构建最终产品,用户对生成器构建的最终产品有更多的控制。
  4. 相似性与差异性:生成器模式与抽象工厂模式有相似之处,都返回由其他一些对象组成的类的对象。但两者之间存在主要区别,抽象工厂模式返回一个类族,而生成器模式逐步按照次序构建一个复杂的对象。

生成器模式在某些情况下可能会存在一些缺点和局限性,主要包括以下几个方面:

  1. 生成器模式所创建的产品一般具有较多的共同点,其组成部分相似:如果产品差异过大,则不适合采用该模式,因此其使用范围受到一定的限制。
  2. 如果产品内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化:这可能导致系统变得庞大。
  3. 适用性:生成器模式适用于创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  4. 增加新的具体的生成器时,不必修改指挥者的代码:但是,当产品对象变化时,往往需要修改指挥者类,这可能会违反开闭原则。

在这里插入图片描述

应用场景

生成器模式的应用场景主要有以下几种:

  1. 创建复杂的对象:当创建一个对象需要多个步骤,并且每个步骤可能有多个选择时,可以使用生成器模式。将对象的构建过程分解为多个部分,每个部分由一个具体的生成器类负责构建,通过控制生成器的组合顺序,可以构建出不同的对象。
  2. 构建流程定义:生成器模式可以用于构建复杂的流程定义,将流程的各个步骤抽象为生成器类,通过组合生成器的方式定义整个流程。
  3. 状态改变:在某些情况下,当对象的状态发生改变时,需要调用多个方法才能完成。使用生成器模式可以将状态的改变分解为多个方法,每个方法负责改变对象的一部分状态,从而提高代码的可读性和可维护性。
  4. 实现插件架构:生成器模式可以用于实现插件架构,通过定义一个接口和多个实现类,将插件的加载和卸载分解为多个步骤,每个步骤由一个具体的生成器类负责实现。这样可以在运行时动态地添加或删除插件,而不需要修改主程序。

在这里插入图片描述

生成器模式和工厂模式的区别

生成器模式与工厂模式在多个方面存在差异:

  1. 目的:生成器模式通常用于创建更为复杂的对象,因为对象的创建过程更为复杂,将对象的创建过程独立出来组成一个新的类——Director类。而工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品。
  2. 构建方式:生成器模式注重按步骤创建一个复杂的对象,一步一步的建立起该对象,最后组合对象最后返回对象。而工厂模式(或抽象工厂)是强调一次性的返回某个对象。
  3. 类数量与依赖关系:生成器模式中的每个具体的生成器都独立于程序的其他生成器,改善了程序的模板化,并且使添加其他生成器变得相对简单。而工厂模式的类数量和依赖关系可能会更多。

生成器模式与工厂模式的区别主要体现在目的、构建方式和类数量与依赖关系等方面。可以根据具体的需求选择更适合的模式。

在这里插入图片描述

代码示例

Java实现生成器模式

以下是Java实现生成器模式的示例代码:

// 抽象生成器
public interface Generator<T> {
    T next();
}

// 具体生成器1
public class ConcreteGenerator1 implements Generator<Integer> {
    private int count = 0;
    
    @Override
    public Integer next() {
        return count++;
    }
}

// 具体生成器2
public class ConcreteGenerator2 implements Generator<String> {
    private String prefix = "Hello ";
    private int count = 0;
    
    @Override
    public String next() {
        return prefix + count++;
    }
}

// 指挥者类
public class Director {
    private Generator<?> generator;
    
    public Director(Generator<?> generator) {
        this.generator = generator;
    }
    
    public void setGenerator(Generator<?> generator) {
        this.generator = generator;
    }
    
    public Object generate() {
        Object result = generator.next();
        System.out.println("Generated: " + result);
        return result;
    }
}

使用示例:

public class Client {
    public static void main(String[] args) {
        // 创建具体生成器1和具体生成器2对象
        Generator<Integer> gen1 = new ConcreteGenerator1();
        Generator<String> gen2 = new ConcreteGenerator2();
        
        // 创建指挥者对象,并设置具体生成器对象1和具体生成器对象2为指挥者对象的具体生成器对象
        Director director = new Director(gen1);
        director.setGenerator(gen2); // 设置新的生成器对象2为指挥者对象的具体生成器对象,此时指挥者对象将不再使用生成器对象1,而是使用新的生成器对象2来生成对象。这符合生成器模式的特点。
        
        // 指挥者对象调用generate方法来依次生成两个对象,并打印输出结果。由于在指挥者对象中使用了多态性,所以生成的对象的类型由指挥者对象所设置的具体生成器对象的类型决定。这里首先会打印出生成器对象1生成的Integer类型的对象,然后打印出生成器对象2生成的String类型的对象。因此输出结果如下:
        System.out.println(director.generate()); // Generated: 0, output Integer type object. 0 is the first value generated by concrete generator 1.
        System.out.println(director.generate()); // Generated: Hello 0, output String type object. "Hello " is the prefix of concrete generator 2, and 0 is the first value generated by concrete generator 2. 0 is the second value generated by director, and it is generated by concrete generator 2. Therefore, the second value generated by director is a String type object. In this example, we only use director to generate two objects, so the second value generated by director is also the last value generated by director. If we use director to generate more objects, the last value generated by director will be the value returned by the last call of director.generate() method. The director class uses the strategy pattern to encapsulate the algorithm of generating objects, and each concrete generator implements its own algorithm of generating objects. The director class can use different concrete generator objects to generate different types of objects according to different requirements. This is a common design pattern in software development, and it can help us to solve a lot of common problems in software development, such as generating complex objects, processing complex data structures, etc.

Python实现生成器模式

以下是Python实现生成器模式的示例代码:

# 定义生成器函数
def simple_generator():
    yield 1
    yield 2
    yield 3

# 使用生成器函数
for i in simple_generator():
    print(i)

输出结果:

1
2
3

在Python中,使用yield关键字定义一个生成器函数,然后在循环中使用该生成器函数。每次调用生成器函数时,它会返回生成器对象,然后迭代器会从上次停止的地方继续执行,直到遇到下一个yield语句。在上面的示例中,我们定义了一个简单的生成器函数simple_generator,它生成了三个整数1、2和3。然后我们使用for循环遍历生成器对象,并打印每个生成的整数。由于生成器是惰性计算的,因此在每次迭代时才会计算下一个值,而不是一次性计算所有值。这使得生成器非常适合处理大量数据或需要节省内存的情况。

在这里插入图片描述

生成器模式在spring中的应用

生成器模式在Spring框架中有多种应用场景,以下是一些常见的应用示例:

  1. 创建复杂的对象:Spring中经常需要创建复杂的对象,这些对象可能包含多个属性,每个属性的值可能需要通过不同的方法获取。使用生成器模式可以将对象的创建过程分解为多个步骤,每个步骤由一个具体的生成器类负责构建,通过控制生成器的组合顺序,可以构建出不同的对象。
  2. 构建流程定义:Spring中可以使用生成器模式定义复杂的流程,将流程的各个步骤抽象为生成器类,通过组合生成器的方式定义整个流程。这样可以使得流程的维护和扩展更加灵活和方便。
  3. 状态改变:在某些情况下,当对象的状态发生改变时,需要调用多个方法才能完成。使用生成器模式可以将状态的改变分解为多个方法,每个方法负责改变对象的一部分状态,从而提高代码的可读性和可维护性。
  4. 实现插件架构:Spring中可以使用生成器模式实现插件架构,通过定义一个接口和多个实现类,将插件的加载和卸载分解为多个步骤,每个步骤由一个具体的生成器类负责实现。这样可以在运行时动态地添加或删除插件,而不需要修改主程序。

生成器模式在Spring中应用广泛,可以提高代码的可读性和可维护性,降低程序的复杂度,使得程序更加灵活和易于扩展。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OCP NVME SSD规范解读-1

OCP&#xff08;Open Compute Project&#xff09;是一个由Facebook于2011年发起的开源项目。其目标是重新设计和优化数据中心的硬件&#xff0c;包括服务器、存储、网络设备等&#xff0c;以提高效率&#xff0c;降低运营成本&#xff0c;并推动技术的创新和标准化。 在OCP中&…

thinkphp6.0的workerman在PHP8.0下报错

一、我先升级了thinkphp6.0到最新版本&#xff1a; composer update topthink/framework二、结果提示我composer版本过低&#xff0c;需要升级到2&#xff0c;于是我又升级了composer composer self-update 三、我又升级了workerman: composer require topthink/think-work…

主机安全技术措施

目录 身份鉴别 进阶 访问控制 进阶 安全审计 进阶 ​编辑 剩余信息保护 入侵防范 进阶 恶意代码防范 资源控制 身份鉴别 进阶 访问控制 进阶 安全审计 进阶 剩余信息保护 入侵防范 进阶 恶意代码防范 资源控制 ~over~

【回溯】符号三角形问题Python实现

文章目录 [toc]问题描述回溯法时间复杂性Python实现 个人主页&#xff1a;丷从心 系列专栏&#xff1a;回溯法 问题描述 下图是由 14 14 14个“ ”和 14 14 14个“ − - −”组成的符号三角形&#xff0c; 2 2 2个同号下面都是” “&#xff0c; 2 2 2个异号下面都是“ −…

如何编写高效清晰的嵌入式C程序

作为嵌入式工程师&#xff0c;怎么写出效率高、思路清晰的C语言程序呢? 要用C语言的思维方式来进行程序的构架构建 要有良好的C语言算法基础&#xff0c;以此来实现程序的逻辑构架 灵活运用C语言的指针操作 虽然看起来以上的说法很抽象&#xff0c;给人如坠雾里的感觉&…

智能优化算法应用:基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于厨师算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.厨师算法4.实验参数设定5.算法结果6.参考文献7.MA…

reactive和TypeScript标注数据类型-ts使用方法

一、vite项目中<script setup lang"ts"> : lang"ts" 是表明支持ts校验&#xff08;ts 全称typescript,是es6语法&#xff0c;是javascript的超集强类型编程语言&#xff0c;类似java&#xff0c;定义变量类型后&#xff0c;赋值类型不一致&#xff0…

网站管理员应该知道的:一款免费、简单、强大的 WAF(雷池社区版)

作为网站管理员&#xff0c;一定会关注网站是否安全&#xff0c;是否能够抵御黑客的攻击&#xff0c;是否能够保护数据和用户。可能已经听说过 WAF&#xff08;Web Application Firewall&#xff0c;Web 应用防火墙&#xff09;&#xff0c;一种能够在应用层对 Web 流量进行检测…

图灵日记之java奇妙历险记--输入输出方法数组

目录 输入输出输出到控制台从键盘输入使用 Scanner 读取字符串/整数/浮点数使用 Scanner 循环读取 猜数字方法方法定义方法调用的执行过程实参和形参的关系(重要)方法重载 数组数组的创建数组的初始化动态初始化静态初始化 数组的使用元素访问遍历数组 数组是引用类型null数组应…

大创项目推荐 深度学习OCR中文识别 - opencv python

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…

SQL实践篇(三):什么是Redis

文章目录 简介Redis是什么&#xff0c;为什么这么快&#xff1f;Redis的数据类型字符串Hash字符串列表字符串集合有序字符串集合其他数据类型 总结参考文献 简介 Redis是一种基于内存的键值数据库&#xff0c;键值数据库会使用哈希表存储key和value。其中key和value可以是任何…

【力扣】199.二叉树的右视图

看到这个题目的一瞬间&#xff0c;我想递归&#xff0c;必须用递归。最近被递归折磨的有点狠&#xff0c;但是我感觉我快要打败它了&#xff0c;就是现在稍稍有点处于劣势。不过没关系&#xff0c;来日方长不是。 法一&#xff1a;递归 题解&#xff1a; 之前想的就是先递归&…

python:改进型鳟海鞘算法(SSALEO)求解23个基本函数

一、改进型鳟海鞘算法SSALEO 改进型鳟海鞘算法&#xff08;SSALEO&#xff09;由Mohammed Qaraad等人于2022年提出。 参考文献&#xff1a;M. Qaraad, S. Amjad, N. K. Hussein, S. Mirjalili, N. B. Halima and M. A. Elhosseini, "Comparing SSALEO as a Scalable Larg…

50个免费的 AI 工具,提升工作效率(附网址)

上次我们已经介绍了20个精选的提高工作效率的免费AI工具&#xff0c;但如果你觉得这些AI工具还不过瘾的话&#xff0c;想进一步成为职场中最了解AI的人&#xff0c;本文将汇总介绍免费最新的50个AI工具。 DeepSwap DeepSwap 是一个基于 AI 的工具&#xff0c;适用于想要制作令人…

Kafka生产环境问题总结与性能优化实践

Kafka可视化管理工具kafka-manager 安装及基本使用可参考: httos://wwwcnbloas.com/dadonaaa/o/8205302.html 线上环境规划 1. 消息丢失情况: 消

【MATLAB库函数系列】线性调频Z(Chirp-Z,CZT)的MATLAB源码和C语言实现

在上一篇博客 【数字信号处理】线性调频Z(Chirp-Z,CZT)算法详解 已经详细介绍了CZT变换的应用背景和原理,先回顾一下: 回顾CZT算法 采用 FFT 算法可以很快计算出全部 N N N点 DFT 值,即Z变换 X ( z ) X(z) <

LaTex插入图片、插入表格、插入公式

目录 一、插入图片 1&#xff09;改变图片的大小、旋转图片 2&#xff09;标签和交叉引用 3&#xff09;插入单排多图无小标题共享大标题 4&#xff09;单排变多排 5&#xff09;图片的位置 6&#xff09;图片横跨双栏 二、插入表格 1&#xff09;合并单元格 2&#…

RHCE9学习指南 第9章 权限管理

9.1 所有者所属组 为了了解所有者和所属组的概念&#xff0c;我们先看图9-1。 图9-1 用房子来帮助理解所有者和所属组 张老板是公司老板&#xff0c;买了一套房作为员工宿舍给A部门的员工居住。张老板是房主&#xff0c;所以他对房子具有很多权限&#xff0c;A部门员工只能具…

【开源】基于JAVA语言的大学生相亲网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询会员4.2 查询相亲大会4.3 新增留言4.4 查询新闻4.5 新增新闻 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的大学生相亲网站&#xff0c;包含了会员管理模块、新闻管…

k8s实战之ELK日志管理

首先查看总体流程 首先创建namespace apiVersion: v1 kind: Namespace metadata:name: kube-logging 一、首先创建es.yaml --- apiVersion: v1 #kubernetes API版本,采用最新版本v1 kind: Service #资源类型定义为Service metadata: name: elasticsearch-logging # …