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

设计模式简介

设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可复用解决方案,它提供了标准化的代码设计方案提升开发体验。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. Redis缓存同步1-策略介绍

    缓存数据同步策略示意图 在大多数情况下,我们通过浏览器查询到的数据都是缓存数据,如果缓存数据与数据库的数据存在较大差异的话,可能会产生比较严重的后果的.所以,我们应该也必须保证数据库数据.缓存数据的一 ...

  2. html实现原生table并设置表格边框的两种方式

    虽然第三方表格插件多不胜数,但是很多场景还是需要用到原生<table>,掌握html原生table的实现方法,是前端开发的必备技能.例如:print-js打印.html2canvas生成图 ...

  3. RabbitMQ 中 exchange、route、queue 的关系

    从 AMQP 协议可以看出,MessageQueue.Exchange 和 Binding 构成了 AMQP 协议的核心,下面我们就围绕这三个主要组件 从应用使用的角度全面的介绍如何利用 Rabbit ...

  4. EasyExcel · 写excel

    原文地址 通用数据生成 后面不会重复写 private List<DemoData> data() { List<DemoData> list = ListUtils.newA ...

  5. IIC总线学习笔记

    IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板.嵌入式系统或手 ...

  6. 解决pandas 读取csv文件报错

    使用encoding参数: pd.read_csv(path,sep=",",encoding='utf-16') 注意:该参数之后的编码格式,并不是固定的,需要用记事本打开csv ...

  7. word中查找替换不能使用 解决方案

    打开查找,然后点更多,最下面点不限定格式

  8. [mysql]状态检查常用SQL

    前言 使用MySQL自身命令获取数据库服务状态. 连接数 -- 最大使用连接数 show status like 'Max_used_connections'; -- 系统配置的最大连接数 show ...

  9. 使用PySpark计算AUC,KS与PSI

    当特征数量或者模型数量很多的时候,使用PySpark去计算相关指标会节省很多的时间.网上关于使用PySpark计算相关指标的资料较少,这里抛砖引玉,写了三个风控常用的指标AUC,KS和PSI相关的计算 ...

  10. Windows校验文件MD5和SHA值的方法

    1.需求背景 下载或传输文件后,需要计算文件的MD5.SHA256等校验值,以确保下载或传输后的文件和源文件一致 2.校验方法 如上图所示,可以使用Windows自带的certutil命令来计算一个文 ...