本文由葡萄城技术团队首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

设计模式简介

设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可复用解决方案,它提供了标准化的代码设计方案提升开发体验。Node.js 作为一款用来构建可扩展高性能应用的流行平台,自然也遵循设计模式解决通用问题。本文中,我们将讨论 Node.js 中设计模式的重要性并提供一些代码示例。

构建 Node.js 应用为何需要设计模式

设计模式为软件开发提供了一套标准化的解决方案。构建 Node.js 应用时,善用设计模式能够帮助开发者提升代码质量,节约开发时间,减少出错几率。同时也方便开发人员之间的沟通交流。

示例代码

单例模式

该模式用来保证特定的类在整个应用中只能创建唯一实例。Node.js 中,单例模式可以保证在同一个应用中,每个模块只有唯一实例。

class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
} // Your code here
} module.exports = Singleton;

工厂模式

工厂模式用来在不暴露实现逻辑的情况下创建对象。在 Node.js 中,使用工厂模式可以根据用户输入创建不同类型的实例。

class Car {
constructor(name) {
this.name = name;
}
drive() {
console.log(`Driving ${this.name}`);
}
} class CarFactory {
static create(name) {
return new Car(name);
}
} const car1 = CarFactory.create("BMW");
const car2 = CarFactory.create("Audi"); car1.drive(); // Driving BMW
car2.drive(); // Driving Audi

观察者模式

观察者模式通过维护一个被观察对象列表,实现当对象发生改变时发出通知。在 Node.js中,该设计模式用来管理事件和回调。

class EventObserver {
constructor() {
this.observers = [];
} subscribe(fn) {
this.observers.push(fn);
} unsubscribe(fn) {
this.observers = this.observers.filter(subscriber => subscriber !== fn);
} notify(data) {
this.observers.forEach(observer => observer(data));
}
} const eventObserver = new EventObserver(); eventObserver.subscribe(data => console.log(`Subscribed to ${data}`));
eventObserver.notify("some data");

依赖注入模式

在本案例中,定义了一个依赖database 对象的UserService 类。通过将 database 传给 UserService 的构造函数,实现在不修改 UserService 的前提下操作不同数据库对象。

class UserService {
constructor(database) {
this.database = database;
} getUser(id) {
return this.database.query(`SELECT * FROM users WHERE id = ${id}`);
}
} module.exports = UserService;

Promise 模式

在本案例中,通过 fs.promises 模块异步读取文件。readFile 函数返回一个 promise 对象,该 promise对象成功时可以通过 then 方法获取文件内容,失败时可以通过 catch 方法获取错误信息。

const fs = require('fs').promises;

function readFile(filePath) {
return fs.readFile(filePath, 'utf8');
} readFile('example.txt')
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});

Node.js 内建模块中的设计模式

默认情况下,Node.js 本身在其功能中不依赖任何特定的设计模式,但它提供了遵循常见设计模式的内置模块。Node.js 中一些常用的设计模式包括:

模块模式

Node.js 默认使用模块模式将代码组织成可复用、可维护的模块。在 Node.js 中,每个文件都被视为一个模块,开发人员可以使用 require 和 module.exports 语句在文件之间导出或导入代码。

const fs = require('fs');

// 异步读取文件
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
}); // 同步读取文件
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data); // 写入文件
fs.writeFile('file.txt', 'Hello, World!', (err) => {
if (err) throw err;
console.log('文件已写入');
});

事件驱动模式

Node.js 使用事件驱动模式来处理 I/O 操作,如向文件或网络套接字读取和写入数据。事件驱动模式基于观察者模式,允许开发人员创建事件发射器,以便在某些事件发生时通知侦听器。

// 模块定义
const myModule = (function () {
// 私有成员
const privateVar = 'Hello, World!'; function privateMethod() {
console.log(privateVar);
} // 公有成员
return {
publicMethod: function () {
privateMethod();
},
publicVar: 'I am public'
};
})(); // 使用模块
myModule.publicMethod(); // 输出 'Hello, World!'
console.log(myModule.publicVar); // 输出 'I am public'

回调模式

Node.js 使用回调模式来处理异步操作,如读写文件或网络请求。回调模式基于观察者模式,允许开发人员将函数作为参数传递,以便在操作完成时执行。

function fetchData(callback) {
// 模拟异步数据获取
setTimeout(() => {
const data = 'Hello, World!';
callback(null, data); // 第一个参数为错误对象,第二个参数为返回的数据
}, 2000);
} function processData(err, data) {
if (err) {
console.error('出错了:', err);
return;
}
console.log('处理数据:', data);
} fetchData(processData);

中间件模式

中间件是 Express.js 等 Node.js 框架中常用的设计模式。中间件函数是在管道中执行的函数,其中每个函数都可以在将请求或响应对象传递到下一个函数之前修改它们。中间件可用于身份验证、日志记录、错误处理等任务。

// 中间件函数1
function middleware1(req, res, next) {
console.log('执行中间件1');
// 在这里可以对 req 和 res 进行处理
next(); // 调用 next() 将控制权传递给下一个中间件
} // 中间件函数2
function middleware2(req, res, next) {
console.log('执行中间件2');
// 在这里可以对 req 和 res 进行处理
next(); // 调用 next() 将控制权传递给下一个中间件
} // 最终处理函数
function finalHandler(req, res) {
console.log('执行最终处理函数');
// 在这里进行最终的请求处理和响应
res.end('Hello, World!');
} // 使用中间件
function handleRequest(req, res) {
middleware1(req, res, () => {
middleware2(req, res, () => {
finalHandler(req, res);
});
});
} // 创建服务器并处理请求
const http = require('http');
const server = http.createServer(handleRequest); server.listen(3000, 'localhost', () => {
console.log('服务器已启动');
});

依赖注入模式

依赖注入(DI)模式是一种用于管理对象之间依赖关系的设计模式。在 Node.js 中,DI 可用于将依赖项注入到模块中,使它们更加模块化和可重用。DI 可以使用构造函数注入、属性注入或方法注入等技术来实现。

// 用户服务模块
class UserService {
constructor() {
this.users = [];
} addUser(user) {
this.users.push(user);
} getUsers() {
return this.users;
}
} // 用户控制器模块(依赖于用户服务模块)
class UserController {
constructor(userService) {
this.userService = userService;
} addUser(user) {
this.userService.addUser(user);
} getUsers() {
return this.userService.getUsers();
}
} // 使用依赖注入创建用户控制器实例
const userService = new UserService();
const userController = new UserController(userService); // 在用户控制器中添加用户并获取用户列表
userController.addUser('John');
userController.addUser('Mary');
console.log(userController.getUsers()); // 输出:['John', 'Mary']

Promise模式

Promise模式是一种设计模式,用于以更结构化和类似同步的方式处理异步操作。Promise 是表示异步操作最终完成或失败的对象,允许开发人员通过将异步操作连接在一起来编写更具可读性和可维护性的代码。

// 使用 Promise 封装异步函数
function getUserById(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const user = { id, name: 'John' };
resolve(user);
}, 1000);
});
} // 调用异步函数并使用 Promise 链式调用处理结果
getUserById(1)
.then(user => {
console.log(user);
return getUserById(2);
})
.then(user => {
console.log(user);
})
.catch(err => {
console.error(err);
});

总结

设计模式提供了一种结构化方法来解决 Node.js 中的常见编程问题。它们帮助开发人员编写更好、可维护和可扩展的代码。设计模式还为开发人员之间的交流提供了“标准词汇”。设计模式对于使用 Node.js 编写高质量代码至关重要,如果您想了解更多关于前端表格控件的知识,欢迎点击这里

扩展链接:

高级SQL分析函数-如何用窗口函数进行排名计算

3D模型+BI分析,打造全新的交互式3D可视化大屏开发方案

React + Springboot + Quartz,从0实现Excel报表自动化

Node.js中常用的设计模式有哪些?的更多相关文章

  1. node.js中常用的fs文件系统

    fs文件系统模块对于系统文件及目录进行一些读写操作. 模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync(). 异步的 ...

  2. js 中常用的设计模式

    常用的设计模式: 工厂方法模式.单例模式.适配器模式.组合模式.迭代子模式 (23种设计模式) 总体来说设计模式分为三大类: ①创建型模式 共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原 ...

  3. Node.js中的模块化

    每天一篇文章来记录记录自己的成长吧.大二,该静心了.加油~ 好了,废话不多说,今天说说nodejs中的模块化.(注:此文为自己对书nodejs实战的总结) nodejs一个重要的特性就是模块化,模块就 ...

  4. Node.js:常用工具util

    概要:本篇博客的主要内容是介绍node.js的常用工具util. 1.util.inherits util.inherits(constructor,superConstructor)是一个实现对象间 ...

  5. Node.js中环境变量process.env详解

    Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...

  6. node.js中的回调

    同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止.如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待. 异步和非阻塞:这两个术语可以互换使用,指的是基于回调的.允许脚本并行 ...

  7. Cookie和Session在Node.JS中的实践(二)

    Cookie和Session在Node.JS中的实践(二) cookie篇在作者的上一篇文章Cookie和Session在Node.JS中的实践(一)已经是写得算是比较详细了,有兴趣可以翻看,这篇是s ...

  8. 理解 Node.js 中 Stream(流)

    Stream(流) 是 Node.js 中处理流式数据的抽象接口. stream 模块用于构建实现了流接口的对象. Node.js 提供了多种流对象. 例如,对 HTTP 服务器的request请求和 ...

  9. 前端走进机器学习生态,在 Node.js 中使用 Python

    这次给大家带来一个好东西,它的主要用途就是能让大家在 Node.js 中使用 Python 的接口和函数.可能你看到这里会好奇,会疑惑,会不解,我 Node.js 大法那么好,干嘛要用 Python ...

  10. js中常用追加元素的几种方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

随机推荐

  1. C++面试八股文:什么是构造函数?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第29面: 面试官:什么是构造函数? 二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象.构造函数的名称与类的名称相同,并且没有返回类型. ...

  2. 数据结构课后题答案 - XDU_953

    参考书: 数据结构与算法分析(第二版) 作者:荣政 编 出版社:西安电子科技大学出版社 出版日期:2021年01月01日 答案解析:

  3. 强化学习实践:Policy Gradient-Cart pole游戏展示

    摘要:智能体 agent 在环境 environment 中学习,根据环境的状态 state(或观测到的 observation),执行动作 action,并根据环境的反馈 reward(奖励)来指导 ...

  4. CentOS 30分钟部署免费在线客服系统

    前段时间我发表了一系列文章,开始介绍基于 .net core 的在线客服系统开发过程.期间有一些朋友希望能够给出 Linux 环境的安装部署指导,本文基于 CentOS 7.9 来安装部署. 我详细列 ...

  5. Doris写入数据异常提示actual column number in csv file is less than schema column number

    版本信息: Flink 1.17.1 Doris 1.2.3 Flink Doris Connector 1.4.0 写入方式 采用 String 数据流,依照社区网站的样例代码,在sink之前将数据 ...

  6. 利用Redis实现向量相似度搜索:解决文本、图像和音频之间的相似度匹配问题

    在自然语言处理领域,有一个常见且重要的任务就是文本相似度搜索.文本相似度搜索是指根据用户输入的一段文本,从数据库中找出与之最相似或最相关的一段或多段文本.它可以应用在很多场景中,例如问答系统.推荐系统 ...

  7. 深入理解Java虚拟机(JVM):原理、结构与性能优化

    1. 介绍 Java虚拟机(JVM)是Java程序的核心执行引擎,负责将Java源代码编译成可执行的字节码,并在运行时负责解释执行字节码或将其编译成本地机器代码.本文将深入探讨JVM的原理.结构以及性 ...

  8. 关于Tensorflow!目标检测预训练模型的迁移学习

    ​ 前言 关于TF的目标检测迁移学习,我一开始是想通过Tensorflow提供的API,用JS来实现的.但是官方不但没有案例,网上也没有踩坑的博客,加之我又着急要弄水印检测. 于是就在网上看了很多人用 ...

  9. 新一代Kerberos攻击 钻石票据与蓝宝石票据

    新一代Kerberos攻击 | 钻石票据与蓝宝石票据 0x01 前言 在了解票据攻击的过程中,看见了一篇文章使用Rubeus进行钻石票据攻击.但是没有原理,于是抱着学习的心态在Google上寻找文章发 ...

  10. 使用C#创建安装Windows服务程序(最全教程)

    开发语言:C# 开发环境: Visual Studio 2022 微软官方文档:https://learn.microsoft.com/zh-cn/dotnet/framework/windows-s ...