안녕하세요!
저는 최근 Node.js의 인기 있는 디자인과 아키텍처 패턴에 대해 자세히 알아보기 위해 여러 지식 리소스를 살펴보았습니다. 내 목표는 주로 서버(백엔드) 측에 있었지만, 이를 진행하면서 브라우저(프론트엔드) 프레임워크와 많은 유사점을 발견했습니다. 그 중 일부는 프레임워크에서 직접 사용되기도 했는데, 나도 모르게 이미 사용하고 있었기 때문에 더욱 기뻤습니다.
사용할 수 있는 디자인 패턴은 정말 많습니다. 그래서 이번 글에서는 그 중 10개를 선택하여 좀 더 자세히 설명하기로 했습니다.
즐기세요!
디자인 패턴은 개발자로서 매일 직면하는 문제를 해결하기 위한 입증되고 철저한 테스트를 거친 솔루션입니다. 이러한 패턴은 모범 사례를 장려하고 소프트웨어 아키텍처를 설계 및 개발하는 동안 일상적인 문제를 해결하기 위한 구조화된 접근 방식을 구현하는 데 도움이 됩니다. 소프트웨어 엔지니어는 이러한 패턴을 사용하여 유지 관리가 가능하고 안전하며 안정적인 시스템을 개발할 수 있습니다.
Node.js는 유연성 덕분에 특정 패턴을 고수하도록 강요하지 않고 대신 작업에 필요한 패턴만 선택할 수 있는 자유를 제공합니다. 이것이 바로 내 생각에 이것이 오늘날 매우 널리 사용되는 이유입니다(그리고 JavaScript 덕분입니다 :D).
아래에는 제가 좋아하는 5가지 디자인 패턴이 나열되어 있습니다.
이 패턴은 하나의 인스턴스만 가질 수 있고 이에 대한 전역 액세스를 제공하는 클래스에 관한 것입니다. 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 medicine = Redis.getInstance(); const redisTwo = Redis.getInstance(); console.log(redisOne === RedisTwo); // it will result to `true` redisOne.connect(); console.log(redisOne.connection) // 'Redis connected' console.log(redisTwo.connection) // 'Redis connected'
이 접근 방식은 Redis에 대한 연결이 하나만 존재하도록 보장하고 연결 중복을 방지합니다.
이 패턴을 사용하면 생성할 객체의 클래스를 지정하지 않고도 새 객체를 생성할 수 있습니다. 덕분에 코드 가독성과 재사용성을 향상시키는 데 도움이 되는 객체 생성을 추상화하고 있습니다.
class Character { constructor(name, health) { this.name = name; 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.name) // Powerful Mage console.log(warrior.name) // 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
게시자와 구독자를 연결하지 않고도 여러 개체를 업데이트할 수 있는 이벤트 처리 및 비동기식 워크플로에 정말 유용한 패턴입니다.
이 패턴은 초기/원래 인스턴스에 영향을 주지 않고 새로운 기능으로 기존 기능을 확장하는 데 매우 유용합니다. TypeScript의 완벽한 지원 덕분에 Nest.js 프레임워크에서 널리 사용되지만 일반 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);
이 접근 방식을 사용하면 시스템 요소를 필요할 때 삽입할 수 있는 독립 엔터티로 추출할 수 있습니다.
Vue, Nuxt, JavaScript 또는 기타 유용한 기술에 대해 자세히 알아보려면 이 링크를 클릭하거나 아래 이미지를 클릭하여 VueSchool을 확인하세요.
일상 작업이나 사이드 프로젝트에 도움이 될 수 있는 최신 Vue 또는 Nuxt 애플리케이션을 구축하는 동안 가장 중요한 개념을 다룹니다.
잘했어요! Node.js에서 특정 디자인 패턴이 작동하는 방식과 이를 구현하는 방법을 배웠습니다.
몸조심하시고 다음에 만나요!
그리고 언제나처럼 즐거운 코딩을 하시나요 ?️
위 내용은 Node.js에서 알아야 할 5가지 디자인 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!