こんにちは!
私は最近、Node.js の一般的なデザインとアーキテクチャ パターンについて詳しく学ぶために、複数のナレッジ リソースを調べました。私の目的は主にサーバー (バックエンド) 側でしたが、それらを検討していくうちに、ブラウザー (フロントエンド) フレームワークと多くの類似点があることに気づきました。それらの中には、フレームワークで直接使用されているものもあります。私はそれを知らずにすでに使用していたので、さらに嬉しくなりました?
使えるデザインパターンはたくさんあるので、この記事ではその中から 10 個を選んで詳しく説明することにしました。
お楽しみください!
デザイン パターンは、私たち開発者が毎日遭遇する問題を解決するための、実績があり、実証済みのソリューションです。これらのパターンは、ベスト プラクティスを推進し、ソフトウェア アーキテクチャの設計と開発中に日常の問題を解決するための構造化されたアプローチを実装するのに役立ちます。ソフトウェア エンジニアは、これらのパターンを使用して、保守可能で安全かつ安定したシステムを開発できます。
Node.js はその柔軟性により、特定のパターンに固執することを強制せず、タスクに必要なパターンだけを自由に選択できます。それが、今日これが非常に広く使用されている理由だと私は考えています (ちなみに JavaScript のおかげです :D)。
以下に、私が気に入った 5 つのデザイン パターンのリストを示します。
このパターンはすべて、インスタンスを 1 つだけ持ち、そのインスタンスへのグローバル アクセスを提供できるクラスに関するものです。モジュールは 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 への接続が 1 つだけになることが保証され、接続の重複が防止されます。
このパターンを使用すると、作成されるオブジェクトのクラスを指定せずに新しいオブジェクトを作成できます。そのおかげで、コードの可読性と再利用性の向上に役立つオブジェクト作成を抽象化しています:
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 中国語 Web サイトの他の関連記事を参照してください。