🔥 解锁Node.js中的五大设计模式
前言
大家好,我是倔强青铜三。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。
五种必知的Node.js设计模式
🟢 什么是设计模式?
设计模式是经过验证并反复测试的解决方案,用于解决我们作为开发人员每天遇到的问题。这些模式有助于推广最佳实践,并在设计和开发软件架构时实施结构化方法来解决日常问题。软件工程师通过使用这些模式可以开发出可维护、安全且稳定的系统。
Node.js由于其灵活性,并不强制您遵循某些模式,而是给予您选择所需模式的自由。这就是为什么我认为它今天被广泛使用的原因(顺便提一下,还得益于JavaScript :D)。
✅ Node.js中五种流行的设计模式
下面,您将看到我所喜欢的五种选定设计模式的列表。
单例模式
这种模式涉及只能有一个实例的类,并提供全局访问。在Node.js中,模块可以被缓存并在整个应用程序中共享,这将有助于提高资源效率。一个常见的单例模式示例是用于连接某些第三方服务(如数据库、缓存服务、电子邮件提供程序等)的模块,它在Nest.js框架中被广泛使用。让我们看看以下示例:
class Redis {
constructor() {
this.connection = null;
}
static getInstance() {
if (!Redis.instance) {
Redis.instance = new Redis(options);
}
return Redis.instance;
}
connect() {
this.connection = 'Redis connected'
}
}
然后我们可以这样使用它:
const redisOne = Redis.getInstance();
const redisTwo = Redis.getInstance();
console.log(redisOne === redisTwo); // 它会返回 `true`
redisOne.connect();
console.log(redisOne.connection) // 'Redis connected'
console.log(redisTwo.connection) // 'Redis connected'
这种方法确保了只有一个到Redis的连接,并防止了连接的重复。
工厂模式
通过这种模式,您可以创建新对象,而无需指定将要创建的对象类。这有助于抽象对象创建,可以提高代码的可读性和可重用性:
class Character {
constructor(type, health) {
this.type = type;
this.health = health;
}
}
class CharacterFactory {
createCharacter(name) {
switch(name) {
case 'mage':
return new Character('Powerful Mage', 8);
case 'warrior':
return new Character('Courageous Warrior', 10);
case 'rogue':
return new Character('Sneaky Rogue', 9)
default:
return new Error('Unknown character');
}
}
}
然后我们可以这样使用它:
const characterFactory = new CharacterFactory();
const mage = characterFactory.createCharacter('mage');
const warrior = characterFactory.createCharacter('warrior');
console.log(mage.type) // Powerful Mage
console.log(warrior.type) // Courageous Warrior
这种方法允许工厂的使用者使用工厂代码而不是直接使用Character类的构造函数。
观察者模式
这种模式的工作原理是,您将有一个管理称为观察者的依赖元素列表的实体,并在状态更改时通知它们。这种模式在Vue.js框架中广泛使用,可以这样实现:
class Topic {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
unsubscribe(observer) {
this.observers = this.observers.filter(o => o !== observer);
}
notify(data) {
this.observers.forEach(o => o.update(data));
}
}
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received ${data}`);
}
}
然后你可以这样使用它:
const topic = new Topic();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
topic.subscribe(observer1);
topic.subscribe(observer2);
topic.notify('Hello World');
// Observer 1 received Hello World
// Observer 2 received Hello World
topic.unsubscribe(observer2);
topic.notify('Hello Again');
// Observer 1 received Hello Again
对于事件处理和异步工作流程来说,这是一个非常有用的模式,它允许更新多个对象,而无需将发布者耦合到订阅者。
装饰器模式
这种模式对于在不影响初始/原始实例的情况下用新功能扩展现有功能非常有用。它在Nest.js框架中得到了广泛使用,这要归功于对TypeScript的完全支持,但在常规Node.js中也可以这样使用:
class Character {
constructor() {
this.endurance = 10;
}
getEndurance() {
return this.endurance;
}
}
class CharacterActions {
constructor(character) {
this.character = character;
}
attack() {
this.character.endurance -= 2;
}
rest() {
this.character.endurance += 1;
}
}
然后可以这样使用它:
const character = new Character();
console.log(character.getEndurance()); // 10
const characterWithActions = new CharacterActions(character);
characterWithActions.attack(); // - 2
characterWithActions.rest(); // + 1
console.log(characterWithActions.character.getEndurance()); // 9
通过使用这种模式,我们可以轻松地扩展已经存在的类,而不会影响其核心功能。
依赖注入模式
在这种模式中,类或模块从外部源接收依赖项,而不是在内部注册它们。这种方法允许从系统中提取某些可重用元素,以便更容易地进行测试和维护。它在Nest.js框架中得到了广泛使用,可以这样实现:
class UserService {
constructor(databaseService, loggerService) {
this.db = databaseService;
this.logger = loggerService;
}
async getUser(userId) {
const user = await this.db.findUserById(userId);
this.logger.log(`Fetched user ${user.name}`);
return user;
}
}
然后,你可以这样使用它:
const databaseService = new Database();
const loggerService = new Logger();
const userService = new UserService(databaseService, loggerService);
userService.getUser(1);
这种方法允许您将系统的元素提取为独立的实体,在需要时可以进行注入。
✅ 总结
做得好!您刚刚了解了Node.js中某些设计模式的工作原理以及如何实现它们。
保重,下次见!
祝您编码愉快 🖥️
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。