【设计模式】01- 一文理解常用设计模式-“创建型模式”篇

一、前言

最近在复习设计模式,撰写、整理了内容和代码片段,和大家一起交流学习。

设计模式是软件设计中常见问题的典型解决方案。

二、模式分类

模式可以根据其意图或目的来分类。常见的设计模式包括:

  • 创建型模式提供创建对象的机制, 增加已有代码的灵活性和可复用性;

  • 结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效;

  • 行为型模式负责对象间的高效沟通和职责委派;

本篇文章介绍创建型模式,后续会更新其他两类设计模式。


三、创建型模式概述

创建型模式主要用于对象的创建过程,它隐藏了对象的创建逻辑,使得代码更具灵活性和可维护性。

四、常见创建型模式(配合代码)

1、单例模式(Singleton Pattern)

确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。

// 单例模式示例
const Singleton = (function () {
       let instance;

       function createInstance() {
           const object = new Object({ name: 'Singleton Object' });
           return object;
       }

       return {
           getInstance: function () {
               if (!instance) {
                   instance = createInstance();
               }
               return instance;
           }
       };
   }());
   
   // 使用示例
   const instance1 = Singleton.getInstance();
   const instance2 = Singleton.getInstance();

   console.log(instance1 === instance2); // 输出: true

代码运行结果

2、工厂模式(Factory Pattern)

定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。

解释:工厂模式就像一个工厂,根据不同的需求生产不同的产品。你只需要告诉工厂你需要什么,工厂就会帮你创建出来。

// 工厂模式示例
function CarFactory() {
    this.createCar = function (type) {
        let car;
        if (type === 'sedan') {
            car = new Sedan();
        } else if (type === 'suv') {
            car = new SUV();
        }
        car.drive = function () {
            console.log(`Driving a ${this.constructor.name}`);
        };
        return car;
    };
}
​
function Sedan() {
    this.type = 'Sedan';
}
​
function SUV() {
    this.type = 'SUV';
}
​
// 使用示例
const factory = new CarFactory();
const sedan = factory.createCar('sedan');
const suv = factory.createCar('suv');
​
sedan.drive(); // 输出: Driving a Sedan
suv.drive();   // 输出: Driving a SUV

代码运行结果

3、抽象工厂模式(Abstract Factory Pattern)

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

简单理解:就像一个超级工厂,能生产不同品牌的汽车系列产品。

// 抽象工厂模式示例
// 抽象工厂
function AbstractCarFactory() {
    this.createEngine = function () {
        throw new Error('This method must be overridden!');
    };
    this.createWheel = function () {
        throw new Error('This method must be overridden!');
    };
}
​
// 具体工厂:丰田工厂
function ToyotaFactory() {
    AbstractCarFactory.call(this);
    this.createEngine = function () {
        return new ToyotaEngine();
    };
    this.createWheel = function () {
        return new ToyotaWheel();
    };
}
​
// 具体工厂:本田工厂
function HondaFactory() {
    AbstractCarFactory.call(this);
    this.createEngine = function () {
        return new HondaEngine();
    };
    this.createWheel = function () {
        return new HondaWheel();
    };
}
​
// 丰田发动机
function ToyotaEngine() {
    this.start = function () {
        console.log('Toyota engine started');
    };
}
​
// 丰田车轮
function ToyotaWheel() {
    this.rotate = function () {
        console.log('Toyota wheel rotating');
    };
}
// 本田发动机
function HondaEngine() {
    this.start = function () {
        console.log('Honda engine started');
    };
}
​
// 本田车轮
function HondaWheel() {
    this.rotate = function () {
        console.log('Honda wheel rotating');
    };
}
​
// 使用示例
const toyotaFactory = new ToyotaFactory();
const toyotaEngine = toyotaFactory.createEngine();
const toyotaWheel = toyotaFactory.createWheel();
​
toyotaEngine.start(); // 输出: Toyota engine started
toyotaWheel.rotate(); // 输出: Toyota wheel rotating
​
const hondaFactory = new HondaFactory();
const hondaEngine = hondaFactory.createEngine();
const hondaWheel = hondaFactory.createWheel();
​
hondaEngine.start(); // 输出: Honda engine started
hondaWheel.rotate(); // 输出: Honda wheel rotating
代码运行结果

4、建造者模式(Builder Pattern)

将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。

简单理解:就像建造房子,有不同的建造步骤,最终可以建成不同风格的房子。

// 建造者模式示例
// 产品类:汽车
function Car() {
    this.wheels = null;
    this.engine = null;
    this.color = null;
​
    this.showInfo = function () {
        console.log(`Car with ${this.wheels} wheels, ${this.engine} engine and ${this.color} color`);
    };
}
​
// 建造者类
function CarBuilder() {
    this.car = new Car();
​
    this.setWheels = function (wheels) {
        this.car.wheels = wheels;
        return this;
    };
​
    this.setEngine = function (engine) {
        this.car.engine = engine;
        return this;
    };
​
    this.setColor = function (color) {
        this.car.color = color;
        return this;
    };
​
    this.build = function () {
        return this.car;
    };
}
​
// 使用示例
const builder = new CarBuilder();
const car = builder
   .setWheels(4)
   .setEngine('V8')
   .setColor('Red')
   .build();
​
car.showInfo(); // 输出: Car with 4 wheels, V8 engine and Red color

代码运行结果

 

5、原型模式(Prototype Pattern)

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

简单理解:就像复印文件,有一个原始文件作为模板,然后可以复印出很多份一样的文件。

// 原型模式示例
const carPrototype = {
    brand: 'Unknown',
    model: 'Unknown',
    start: function () {
        console.log(`Starting the ${this.brand} ${this.model}`);
    },
    clone: function () {
        const clone = Object.create(this);
        return clone;
    }
};
​
// 使用示例
const car1 = carPrototype.clone();
car1.brand = 'Toyota';
car1.model = 'Corolla';
​
const car2 = carPrototype.clone();
car2.brand = 'Honda';
car2.model = 'Civic';
​
car1.start(); // 输出: Starting the Toyota Corolla
car2.start(); // 输出: Starting the Honda Civic

代码运行结果


五、小结

设计模式在编程当中还是挺重要的,优点包括但不限于:代码复用性更高、可维护性更强、可扩展性更好。

有时间可以花点时间学习/复习一下,相信对我们的编程技术和编程思维会有很多进步~

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

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

相关文章

数据结构-链式二叉树

文章目录 一、链式二叉树1.1 链式二叉树的创建1.2 根、左子树、右子树1.3 二叉树的前中后序遍历1.3.1前(先)序遍历1.3.2中序遍历1.3.3后序遍历 1.4 二叉树的节点个数1.5 二叉树的叶子结点个数1.6 第K层节点个数1.7 二叉树的高度1.8 查找指定的值(val)1.9 二叉树的销毁 二、层序…

游戏引擎学习第99天

仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:制作一些光场(Light Field) 当前的目标是为游戏添加光照系统,并已完成了法线映射(normal maps)的管道,但还没有创建可以供这些正常映射采样的光场。为了继续推进&…

LSTM变种模型

GRU GRU简介 门控循环神经网络 (Gated Recurrent Neural Network,GRNN) 的提出,旨在更好地捕捉时间序列中时间步距离较大的依赖关系。它通过可学习的门来控制信息的流动。其中,门控循环单元 (Gated Recurrent Unit , GRU) 是…

业务开发 | 基础知识 | Maven 快速入门

Maven 快速入门 1.Maven 全面概述 Apache Maven 是一种软件项目管理和理解工具。基于项目对象模型的概念(POM),Maven 可以从中央信息中管理项目的构建,报告和文档。 2.Maven 基本功能 因此实际上 Maven 的基本功能就是作为 Ja…

新一代SCADA: 宏集Panorama Suite 2025 正式发布,提供更灵活、符合人体工学且安全的应用体验

宏集科技宣布正式推出全新Panorama Suite 2025 SCADA软件!全新版本标志着 Panorama Suite的一个重要里程碑,代表了从 Panorama Suite 2022 开始并跨越三个版本(2022、2023、2025)的开发过程的顶峰。 此次重大发布集中在六个核心主…

PAT乙级真题 — 1080 MOOC期终成绩(java)【测试点3超时】

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计…

【Oracle篇】浅谈执行计划中的多表连接(含内连接、外连接、半连接、反连接、笛卡尔连接五种连接方式和嵌套、哈希、排序合并三种连接算法)

💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…

TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示

知乎的一个问题很有意思:“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节?” 这种问题很适合我这种搞历史的人,大年初一我给出了一个简短的解释,但仔细探究这个问题,我们将会获得 TCP/IP 被定义的过程。 文…

oracle表分区--范围分区

文章目录 oracle表分区分区的原因分区的优势oracle表分区的作用oracle表分区类型一、范围分区二、 创建分区表和使用:1、按照数值范围划分2、按照时间范围3、MAXVALUE2. 向现有表添加新的分区3、 分区维护和重新组织(合并/删除) oracle表分区…

蓝桥杯(B组)-每日一题(求最大公约数最小公倍数)

题目&#xff1a; 代码展现&#xff1a; #include<iostream> using namespace std; int main() {int m,n,x,y;cin>>m>>n;//输入两个整数int b;bm%n;//取余数xm;//赋值yn;while(b)//当余数不为0的时候{xy;//辗转相除求最小公约数yb;bx%y;}cout<<y<&…

基于STM32的学习环境控制系统设计

&#x1f91e;&#x1f91e;大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是学习环境控制。 设备的详细功能见网盘中的文章《21、基于STM32的学习环境控制系统设计》&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1uWSZX2zbZwy9sY…

WPS接入DeepSeek模型

1.wps 下载安装 WPS-支持多人在线协作编辑Word、Excel和PPT文档_WPS官方网站 &#xff08;最好是安装最新的wps&#xff09; 2.offieceAi工具下载安装 软件下载 | OfficeAI助手 下载后安装下载下来的两个工具。安装路径可以自行修改 3.打开WPS,点击文件-》 选项-》信任中心 勾…

4. React 中的 CSS

用例中的干净的脚手架的创建可以参考另一篇文章&#xff1a;3.React 组件化开发React官方并没有给出在React中统一的样式风格&#xff1a; 由此&#xff0c;从普通的css&#xff0c;到css modules&#xff0c;再到css in js&#xff0c;有几十种不同的解决方案&#xff0c;上百…

Unity进阶教程AOI算法原理详解

最新课程《全栈双客户端(Unity/Cocos) TurnKey方案》更新了AOI专题&#xff0c;今天分享一下AOI算法的实现原理。 AOI的功能和作用 在MMORPG网路游戏当中&#xff0c;单服同时在线一般都会有几千人。当有个玩家执行一个操作&#xff0c;理想情况下要把玩家的操作广播同步给单…

w~大模型~合集30

我自己的原文哦~ https://blog.51cto.com/whaosoft/13284996 #VideoMamba 视频理解因大量时空冗余和复杂时空依赖&#xff0c;同时克服两个问题难度巨大&#xff0c;CNN 和 Transformer 及 Uniformer 都难以胜任&#xff0c;Mamba 是个好思路&#xff0c;让我们看看本文是…

【ThreeJS Basics 1-3】Hello ThreeJS,实现第一个场景

文章目录 环境创建一个项目安装依赖基础 Web 页面概念解释编写代码运行项目 环境 我的环境是 node version 22 创建一个项目 首先&#xff0c;新建一个空的文件夹&#xff0c;然后 npm init -y , 此时会快速生成好默认的 package.json 安装依赖 在新建的项目下用 npm 安装依…

Python----PyQt开发(PyQt基础,环境搭建,Pycharm中PyQttools工具配置,第一个PyQt程序)

一、QT与PyQT的概念和特点 1.1、QT QT是一个1991年由The Qt Company开发的跨平台C图形用户界面应用程序开发 框架&#xff0c;可构建高性能的桌面、移动及Web应用程序。也可用于开发非GUI程序&#xff0c;比如 控制台工具和服务器。Qt是面向对象的框架&#xff0c;使用特殊的代…

PostgreSQL 开发利器:Navicat 核心功能与资源攻略

近几年&#xff0c;&#x1f418; PostgreSQL 在全球数据库排名中表现优异。在 2025 年 2 月 DB-Engines 排名中 (如图)&#xff0c;PostgreSQL 稳居第四名&#xff0c;并逐渐逼近第三名的 Microsoft SQL Server&#xff0c;其评分和受欢迎度持续增长&#xff0c;成为开源数据库…

大模型数据集全面整理:444个数据集下载地址

本文针对Datasets for Large Language Models: A Comprehensive Survey 中的 444 个数据集&#xff08;涵盖8种语言类别和32个领域&#xff09;进行完整下载地址整理收集。 2024-02-28&#xff0c;由杨刘、曹家欢、刘崇宇、丁凯、金连文等作者编写&#xff0c;深入探讨了大型语…

【AI大模型】Ollama部署本地大模型DeepSeek-R1,交互界面Open-WebUI,RagFlow构建私有知识库

文章目录 DeepSeek介绍公司背景核心技术产品与服务应用场景优势与特点访问与体验各个DeepSeek-R系列模型的硬件需求和适用场景 Ollama主要特点优势应用场景安装和使用配置环境变量总结 安装open-webui下载和安装docker desktop配置镜像源安装open-webui运行和使用 RagFlow介绍主…