当前位置: 首页 > news >正文

【利用AI让知识体系化】5种创建型模式

在这里插入图片描述

文章目录

  • 创建型模式
    • 简介
    • 工厂模式
    • 抽象工厂模式
    • 单例模式
    • 建造者模式
    • 原型模式

创建型模式

简介

创建型模式,顾名思义,是用来创建对象的模式。在软件开发中,对象的创建往往比一般的编程任务更为复杂,可能涉及到一些琐碎、复杂的过程,例如对象内部的依赖关系确定、对象的实例化方式等。创建型模式的主要功能是将对象的创建过程封装起来,从而隐藏其复杂性,并且可以为客户端提供一种灵活的创建对象的方式。

常见的创建型模式包括:

  1. 工厂模式(Factory Pattern)
  2. 抽象工厂模式(Abstract Factory Pattern)
  3. 单例模式(Singleton Pattern)
  4. 建造者模式(Builder Pattern)
  5. 原型模式(Prototype Pattern)

这些模式可以被分为两类:类创建型模式和对象创建型模式。类创建型模式通过一个类来创建对象实例,而对象创建型模式则通过一个对象来创建新的对象实例。同时,许多创建型模式都执行一些形式的延迟初始化,我们称之为“惰性初始化”,也是许多模式关注的问题之一。

总之,创建型模式主要解决了对象创建过程中的复杂性和灵活性问题,提高了代码的可复用性和可读性。在软件开发中,根据不同的场景和需求选择合适的创建型模式可以帮助开发者更好地完成对象的创建工作。

工厂模式

工厂模式是一种创建型设计模式,它定义了一个用于创建对象的接口,让子类来决定将哪一个类实例化。工厂模式使得创建对象变得更加灵活和可扩展,它将创建具体对象的责任转移给了子类,而不是在客户端代码中直接实例化对象。

工厂模式常用于以下场合:

  1. 对象创建需要复杂的逻辑
  2. 对象的创建涉及到大量的重复代码
  3. 使用工厂模式可以封装类的实例化过程

工厂模式的核心是一个抽象工厂(Factory)类,该类定义了一个创建对象的抽象方法,子类可以通过实现该抽象方法来创建具体的对象。具体工厂类(Concrete Factory)是工厂模式的重要组成部分,主要负责实现抽象工厂类中定义的抽象方法,以便生产出具体的产品。

有两种基本的工厂模式:简单工厂模式和工厂方法模式。简单工厂模式只是用来创建单一类型的对象,而工厂方法模式则可以用来创建一组相关的对象。同时还有一个抽象工厂模式,它用于创建多个产品系列以及产品之间的关联,属于更高层次的模式。

总之,工厂模式可以帮助客户端代码解耦,将对象的实例化过程封装在工厂类中,让程序更加灵活和可扩展。它是一种非常常见的设计模式,被广泛应用于软件开发的各个领域。

这是一个使用 JavaScript 实现的工厂模式的简单示例:

class Product {constructor(name) {this.name = name;}
}class ProductA extends Product {constructor() {super("ProductA");}
}class ProductB extends Product {constructor() {super("ProductB");}
}class Creator {factoryMethod() {}
}class CreatorA extends Creator {factoryMethod() {return new ProductA();}
}class CreatorB extends Creator {factoryMethod() {return new ProductB();}
}

抽象工厂模式

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或者相互依赖对象的接口,而无需指定实现类。简单来说,抽象工厂模式是一种工厂模式的扩展,可以创建一组相关的对象,而不仅仅是一个对象。

抽象工厂模式常用于以下场合:

  1. 当需要创建一系列相关或相互依赖的对象时
  2. 需要提供一个统一的接口,以便客户端通过抽象接口使用多个具体产品中的一种
  3. 由于业务需求的变化,需要支持新的产品系列

抽象工厂模式由抽象工厂、具体工厂、抽象产品和具体产品四个部分组成。

  1. 抽象工厂(Abstract Factory):定义了创建一系列相关或依赖对象的方法。
  2. 具体工厂(Concrete Factory):实现抽象工厂定义的方法,返回一组相关的产品。
  3. 抽象产品(Abstract Product):定义一类产品的接口。
  4. 具体产品(Concrete Product):实现抽象产品的接口,是抽象工厂创建的对象。

抽象工厂模式可以看做是一组工厂方法的组合,它提供了一种更高层次的抽象,能够将多个相关的对象创建放在同一个工厂中,这样可以更好地维护产品之间的兼容性。

总的来说,抽象工厂模式广泛应用于需要创建一组相关或依赖对象的场合,它使得客户端代码与具体产品的实现相分离,提高了程序模块化和可维护性

这是一个使用 JavaScript 实现的简单的抽象工厂模式的示例:

class AbstractProductA {constructor() {if (new.target === AbstractProductA) {throw new Error("Cannot instantiate abstract class");}}methodA() {}
}class AbstractProductB {constructor() {if (new.target === AbstractProductB) {throw new Error("Cannot instantiate abstract class");}}methodB() {}
}class ProductA1 extends AbstractProductA {methodA() {console.log("Product A1 - Method A");}
}class ProductA2 extends AbstractProductA {methodA() {console.log("Product A2 - Method A");}
}class ProductB1 extends AbstractProductB {methodB() {console.log("Product B1 - Method B");}
}class ProductB2 extends AbstractProductB {methodB() {console.log("Product B2 - Method B");}
}class AbstractFactory {createProductA() {}createProductB() {}
}class ConcreteFactory1 extends AbstractFactory {createProductA() {return new ProductA1();}createProductB() {return new ProductB1();}
}class ConcreteFactory2 extends AbstractFactory {createProductA() {return new ProductA2();}createProductB() {return new ProductB2();}
}

在这个示例中,我们定义了两个抽象产品类 AbstractProductAAbstractProductB,以及两个具体的产品类 ProductA1ProductA2,以及 ProductB1ProductB2。然后我们定义了一个抽象工厂类 AbstractFactory,并在其中定义了两个抽象方法 createProductA()createProductB(),分别用于创建 AbstractProductAAbstractProductB 的实例。最后,我们又定义了两个具体的工厂类 ConcreteFactory1ConcreteFactory2,并分别实现了 AbstractFactory 中的抽象方法。在 ConcreteFactory1 中,实现了 createProductA() 返回 ProductA1 的实例,实现了 createProductB() 返回 ProductB1 的实例。在 ConcreteFactory2 中,实现了 createProductA() 返回 ProductA2 的实例,实现了 createProductB() 返回 ProductB2 的实例。

单例模式

单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个访问这个实例的全局点。单例模式在实际开发中经常用于控制资源的使用,例如全局缓存、配置对象、线程池、数据库连接池等。

单例模式保证了系统中一个类只有一个实例,从而避免了多个实例的产生,节省了系统资源,使得代码执行更加高效、可维护和可扩展。同时,单例模式的实现很简单,只需要提供一个静态方法,返回同一个实例即可。

常见的单例模式实现方式有两种:懒汉式单例模式和饿汉式单例模式。

1. 懒汉式单例模式
懒汉式单例模式是指在第一次获取实例时才进行实例化。优点是可以节省系统资源,缺点是会存在线程安全问题,需要加入同步锁来解决。

2. 饿汉式单例模式
饿汉式单例模式是指在程序启动时进行实例化,不管实例是否被使用。优点是不会出现线程安全问题,缺点是可能会浪费资源,因为实例在程序启动时就被创建,可能在之后并没有被使用到。

同时,单例模式的实现也包括线程安全的单例模式(使用双重检查锁等机制确保线程安全)、枚举类型的单例模式等。此外,单例模式也有一些缺点,例如扩展困难、测试困难等,开发者需要根据实际业务场景来灵活运用单例模式。

总之,单例模式是一种非常常用的设计模式,它可以保证系统中某个类只有一个实例,从而提升系统的性能和可维护性。在实际开发中,需要根据具体业务场景来选择单例模式的实现方式,同时需要注意线程安全和可测试性等问题。

这是一个使用 JavaScript 实现的简单的单例模式的示例:

class Singleton {constructor() {if (!Singleton.instance) {Singleton.instance = this;}return Singleton.instance;}someMethod() {console.log("Some method of the Singleton");}
}

在这个示例中,我们定义了一个类 Singleton,并在其构造函数中使用了一个静态变量 instance。当我们创建这个类的实例时,我们先检查它是否已经存在,如果不存在则创建一个新实例并将其存储在静态变量 instance 中,然后返回这个实例。这样,我们就始终只有一个类的实例被创建,并且可以随时访问它的方法。在这里,我们定义了一个方法 someMethod() 作为单例对象的一个例子。

建造者模式

建造者模式是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,可以让同样的构建过程创建不同的表示

建造者模式通常适用于以下情况:

  1. 创建复杂对象时,对象的内部构造非常复杂(多个组件、不同的构造顺序等)
  2. 通过不同的组装顺序可以创建出不同的对象表示
  3. 在对象构造过程中需要进行很多控制,例如参数校验、类型判断等

建造者模式的核心是一个建造者(Builder)和一个指挥者(Director)。建造者负责创建产品的各个部分,而指挥者负责调用建造者来创建产品,并且按照一定的组装顺序来完成产品的创建。建造者模式将一个复杂对象的创建过程进行了拆分,使得在某个步骤出现问题时,不需要整个重新开始构建,只需要针对问题的步骤进行调整即可。

建造者模式的实现通常包括以下几个角色:

  1. 抽象建造者(Builder):定义创建产品各个部分的抽象方法
  2. 具体建造者(Concrete Builder):实现抽象建造者定义的方法,并返回组装好的产品实例
  3. 产品(Product):定义由各个部分组成的复杂对象
  4. 指挥者(Director):负责调用具体建造者来创建产品,在指挥者中也可以定义具体的组装顺序。

在建造者模式中,客户端通常只需关心指挥者和具体建造者,不需要知道产品的具体实现细节。通过将对象的创建和表示分离,建造者模式可以更好地控制对象的创建过程,从而创建出更加灵活和适用的产品。

总的来说,建造者模式适用于创建那些结构复杂,内部组合关系较为复杂的对象。它的实现较为复杂,但是可以提高代码的可复用性和可维护性,同时也可以增加代码的可扩展性。

原型模式

原型模式是一种创建型设计模式,它使用原型实例指定要创建对象的类型,然后通过复制这个原型来创建新的对象。在原型模式中,不需要知道任何对象的创建细节,只需知道需要创建的对象类型即可。

原型模式通过克隆复制一个已有对象来创建新的对象,可以大大减少创建对象的时间,并且可以避免由于手动创建对象而引入的错误。原型模式在实际开发中应用广泛,常用于创建那些具有相似属性的对象,例如创建相似的数据库连接对象或线程池中的线程对象等。

原型模式的核心是原型接口(Prototype),该接口定义了一个克隆自身的方法,并通过该方法来创建新的对象。具体的原型类(Concrete Prototype)实现了原型接口,并实现了克隆方法,用于创建自身的副本。

在使用原型模式时,可以将原型对象缓存在内存中,并在需要时克隆出一个全新的副本来使用。克隆分为浅克隆和深克隆两种方式。浅克隆只会克隆原型对象本身,而不会克隆其引用的对象,深克隆则会将原型对象及其引用的对象一并克隆出来。具体采用哪种方式可以根据具体情况进行选择。

总的来说,原型模式通过复制已有对象的行为来创建新的对象,减少了代码的重复工作,提高了代码的复用性和可维护性。但是需要注意的是,原型对象必须是可复制的,否则无法实现原型模式的效果。

这是一个使用 JavaScript 实现的简单的原型模式的示例:

const prototype = {name: "",getName: function() {return this.name;},setName: function(name) {this.name = name;},clone: function() {return Object.create(this);}
};const objA = Object.create(prototype);
objA.setName("Object A");const objB = objA.clone();
objB.setName("Object B");console.log(objA.getName()); // Output: "Object A"
console.log(objB.getName()); // Output: "Object B"

在这个示例中,我们先创建了一个原型对象 prototype,它包含了属性 name 和方法 getName()setName()clone()。然后我们创建了一个对象 objA,并使用 Object.create() 方法将其原型设置为 prototype。我们调用 setName() 方法来设置 objA 的名字。接下来,我们通过调用 objA.clone() 来克隆这个对象,并将其赋值给 objB。我们再次通过调用 setName() 来设置 objB 的名字,这一次我们输入的是 “Object B”。最后,我们分别调用 getName() 方法来获取 objAobjB 的名字,并将其打印出来。输出结果是 “Object A” 和 “Object B”,验证了原型模式成功工作。

相关文章:

【利用AI让知识体系化】5种创建型模式

文章目录 创建型模式简介工厂模式抽象工厂模式单例模式建造者模式原型模式 创建型模式 简介 创建型模式,顾名思义,是用来创建对象的模式。在软件开发中,对象的创建往往比一般的编程任务更为复杂,可能涉及到一些琐碎、复杂的过程…...

Unity的UnityStats: 属性详解与实用案例

UnityStats 属性详解 UnityStats 是 Unity 引擎提供的一个用于监测游戏性能的工具,它提供了一系列的属性值,可以帮助开发者解游戏的运行情况,从而进行优化。本文将详细介绍 UnityStats 的每个属性值,并提供多个使用例子帮助开发者…...

TDengine集群搭建

我这里用三台服务器搭建集群 1、如果搭建集群的物理节点上之前安装过TDengine先卸载清空,直接执行以下4条命令 rmtaos rm -rf /var/lib/taos rm -rf /var/log/taos rm -rf /etc/taos2、确保集群中所有主机开放端口 6030-6043/tcp,6060/tcp,…...

Android 12.0无源码apk设置默认启动Launcher的相关属性

1.概述 在12.0的系统产品开发中,对于一些产品的需求,需要将一些无源码app的某个MainActivity作为启动Launcher页面的功能实现,由于没有源码,所以需要 利用PMS的安装解析apk的AndroidManifest.xml的时候,在判断是某个Activity的时候,设置Lancher属性来实现某些功能 2.无源…...

js深拷贝和浅拷贝

👉十分钟学会 前端面试题 js 深拷贝与浅拷贝_前端深拷贝和浅拷贝面试题_Mar-30的博客-CSDN博客 目录 背景: 概念:核心是创建新地址 方法: 浅拷贝: Object.assign() 方法:Object.assign(拷贝的对象&am…...

CANopenNode Master 配置

文章目录 CANopenNode 简介CANopenNode 主栈SDO ClientPDO 通讯参数RPDO 通讯参数RPDO 通信参数设置实例TPDO 通讯参数TPDO 通信参数设置实例 PDO 映射参数RPDO 映射参数设置实例TPDO 映射参数设置实例 CANopenNode 简介 CANopenNode 是一个开源的免费的开源 CANopen 协议栈。…...

HW之轻量级内网资产探测漏洞扫描工具

简介 RGPScan是一款支持弱口令爆破的内网资产探测漏洞扫描工具,集成了Xray与Nuclei的Poc 工具定位 内网资产探测、通用漏洞扫描、弱口令爆破、端口转发、内网穿透、SOCK5 主机[IP&域名]存活检测,支持PING/ICMP模式 端口[IP&域名]服务扫描 网…...

算法练习-2:送外卖

n 个小区排成一列,编号为从 0 到 n-1 。一开始,美团外卖员在第0号小区,目标为位于第 n-1 个小区的配送站。 给定两个整数数列 a[0]~a[n-1] 和 b[0]~b[n-1] ,在每个小区 i 里你有两种选择: 1) 选择a:向前 a[…...

八股总结(六):Android基础:四大组件与UI控件

文章目录 Activity一个APP的启动过程基本概念总图zygote是什么?有什么作用?SystemServer是什么?有什么用,与zygote的关系是什么?为什么称为服务端对象?APP、AMS、zygote是三个独立的进程,他们之…...

【P46】JMeter 响应断言(Response Assertion)

文章目录 一、响应断言(Response Assertion) 参数说明二、准备工作三、测试计划设计3.1、包括3.2、匹配3.3、相等3.4、字符串3.5、字符串3.6、或者 一、响应断言(Response Assertion) 参数说明 可以对 Jmeter 取样器的响应消息进…...

19-02 基于业务量级的架构技术选型演进

从零开始——单服务应用 单体应用技术选型 (GitHub、Gitee…)搜索是否有线程的产品用最熟悉的技术,最快的速度上线如果有经费:考虑商业化解决方案 个人小程序怎么做技术选型的 搜索是否有快速搭建下程序的软件技术选型 后端技…...

Server - 高性能的 PyTorch 训练环境配置 (PyTorch3D 和 FairScale)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/130863537 PyTorch3D 是基于 PyTorch 的 3D 数据深度学习库,提供了高效、模块化和可微分的组件,以简化 3D 深度学…...

小猫踩球-第14届蓝桥杯省赛Scratch中级组真题第2题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第137讲。 小猫踩球,本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程中级组真题第2题&#xf…...

嵌入式开发从入门到精通之第二十一节:三轴加速度传感器(BMA250E)

目录 1、工作模式 2、中断支持的模式 2.1 新数据的产生 2.2 任何斜率的变化的监测...

代码随想录算法训练营第三十六天|435. 无重叠区间 763.划分字母区间 56. 合并区间

目录 LeeCode 435. 无重叠区间 LeeCode 763.划分字母区间 LeeCode 56. 合并区间 LeeCode 435. 无重叠区间 435. 无重叠区间 - 力扣(LeetCode) 思路1:按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉…...

shell 脚本

Shell概述 shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核 脚本入门 脚本格式 脚本以#!/bin/bash开头(指定解析器) helloworld # 创建脚本 [linuxlocalhost datas]$ cat helloworld.sh #!/bin/bas…...

Linux :: 【基础指令篇 :: 用户管理(补充):(4)】::用户切换

前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit。 学习集: C 入门到入土!!!学习合集Linux 从命令到网络再到内核!学习合集 目录索引&am…...

打印机无法扫描的原因及解决方法

在家庭和办公环境中,打印机已成为不可或缺的设备。它不仅可以打印文件,还可以扫描文档并将它们转换为数字数据。但有时,打印机可能无法扫描文档或图片。以下是可能导致这些问题的原因和解决方法。 出现打印机无法扫描的原因: 1.…...

【Mysql】 数据类型

文章目录 【Mysql】 数据类型数据类型分类数值类型1. tinyint类型2. bit类型3. 小数类型 字符串类型1.char2.varchar3. 日期和时间类型4. enum 和 set 【Mysql】 数据类型 mysql中数据类型的作用: 约束操作者的行为更清晰的代码逻辑不同的功用 – 例如&#xff0c…...

mysql中如何使用乐观锁和悲观锁

MySQL中可以使用SELECT ... FOR UPDATE语句来实现悲观锁。这个语句会在查询时锁定被查询的行,在事务结束前都不会释放锁。 例如,我们可以使用以下的 SQL 语句来锁定一个特定的行: BEGIN; SELECT * FROM table WHERE id 1 FOR UPDATE; ... C…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

DiscuzX3.5发帖json api

参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

sshd代码修改banner

sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...