ホームページ >ウェブフロントエンド >jsチュートリアル >ソフトウェア設計パターン: すべての優れたアプリの背後にある秘密のソース
説明書なしでレゴ セットを組み立てることを想像してみてください。確かに、漠然と宇宙船に似たものが完成するかもしれませんが、おそらく、カラフルなカオスの山が完成するでしょう。コーディングの世界では、デザイン パターンは LEGO マニュアルのようなものです。一般的な問題を解決するための実証済みの青写真が得られ、コードがよりクリーンで効率的、保守しやすくなります。
しかし、心配しないでください。これはコーディングの原則に関する無味乾燥な講義ではありません。これは、JavaScript の最も一般的なデザイン パターンのいくつかについての楽しい小さなガイドであり、これらの概念を理解しやすくする現実世界の例えが含まれていると考えてください。
シングルトン パターンは、クラスにインスタンスが 1 つだけ存在することを保証し、そのインスタンスへのグローバル アクセス ポイントを提供します。テレビのリモコンが 1 つあるようなものです。音量の制御、チャンネルの変更、電源オフを行うのに複数のリモコンは必要ありません。必要なのは 1 つのリモコンだけです。
JavaScript では、このパターンはグローバル アプリケーションの状態を管理するためによく使用されます。たとえば、電子商取引 Web サイトにショッピング カートがある場合、カートと対話するすべてのコンポーネント (商品の追加、商品の削除、チェックアウトなど) がカートの同じインスタンスを参照するようにする必要があります。シングルトンは、これらすべてのアクションがカートの別のコピーではなく、同じカートに影響を与えることを保証します。
class ShoppingCart { constructor() { if (!ShoppingCart.instance) { this.items = []; ShoppingCart.instance = this; } return ShoppingCart.instance; } addItem(item) { this.items.push(item); } getItems() { return this.items; } } const cart1 = new ShoppingCart(); const cart2 = new ShoppingCart(); cart1.addItem('Laptop'); console.log(cart2.getItems()); // ['Laptop']
Observer パターンは、オブジェクトの同期を維持することがすべてです。 1 つのオブジェクトが変更されると、他のオブジェクトもそれを知る必要があります。これはグループ チャットのようなもので、全員が常に最新情報を共有します。誰かが週末の計画を変更すると、グループの全員がメモを受け取ります。
JavaScript では、このパターンはイベント処理システムでよく使用されます。ソーシャル メディア アプリを構築しているとします。誰かが投稿にいいねをした場合、いいね数を更新し、投稿の作成者に通知し、場合によってはアニメーションをトリガーする必要があります。 Observer パターンを使用すると、これらのさまざまなコンポーネントを直接接続せずに更新し続けることができます。
class Subject { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { update(data) { console.log(`Observer received: ${data}`); } } const subject = new Subject(); const observer1 = new Observer(); const observer2 = new Observer(); subject.subscribe(observer1); subject.subscribe(observer2); subject.notify('New post liked!'); // Output: Observer received: New post liked! // Output: Observer received: New post liked!
Factory パターンは、作成されるオブジェクトの正確なクラスを指定せずにオブジェクトを作成することを目的としています。クッキー抜き型を想像してみてください。カッターを押し下げるまで、生地がどのような形になるか正確にはわかりませんが、クッキーが得られることはわかっています。
このパターンは、共通のインターフェイスまたは構造を共有しているものの、基礎となる実装が異なるオブジェクトのコレクションがある場合に特に便利です。たとえば、ゲームにはさまざまな種類の敵 (ゾンビ、吸血鬼、狼男) が存在しますが、それらはすべて、体力、速度、攻撃力などの共通の特性を共有しています。ファクトリーを使用すると、特定のタイプを気にせずにこれらの敵を作成できます。
class Enemy { constructor(type) { this.type = type; this.health = 100; } attack() { console.log(`${this.type} attacks with ${this.attackPower}`); } } class EnemyFactory { createEnemy(type) { let enemy; if (type === 'zombie') { enemy = new Enemy('Zombie'); enemy.attackPower = 10; } else if (type === 'vampire') { enemy = new Enemy('Vampire'); enemy.attackPower = 20; } else if (type === 'werewolf') { enemy = new Enemy('Werewolf'); enemy.attackPower = 30; } return enemy; } } const factory = new EnemyFactory(); const zombie = factory.createEnemy('zombie'); zombie.attack(); // Zombie attacks with 10 const vampire = factory.createEnemy('vampire'); vampire.attack(); // Vampire attacks with 20
モジュール パターンは、すべてが適切に配置される、整理されたワークスペースのようなものです。これにより、コードのさまざまな部分を整理してカプセル化し、グローバル名前空間が乱雑になるのを防ぐことができます。
このパターンは、JavaScript でパブリックおよびプライベートの変数や関数を作成する場合に特に役立ちます。たとえば、ライブラリやプラグインを構築するとき、特定のメソッドを外部に公開し、他のメソッドを非表示にしたい場合があります。 Module パターンを使用すると、まさにそれが可能になります。
const Calculator = (function() { let result = 0; function add(x) { result += x; return result; } function subtract(x) { result -= x; return result; } function multiply(x) { result *= x; return result; } function divide(x) { if (x !== 0) { result /= x; return result; } else { console.error('Cannot divide by zero'); } } return { add, subtract, multiply, divide, getResult: () => result, }; })(); console.log(Calculator.add(10)); // 10 console.log(Calculator.subtract(2)); // 8 console.log(Calculator.multiply(3)); // 24 console.log(Calculator.divide(4)); // 6
アダプター パターンを使用すると、互換性のないインターフェイスを連携させることができます。海外旅行時に使うプラグアダプターのようなものだと考えてください。ノートパソコンの充電器のプラグが別の国の壁コンセントに差し込まれない場合がありますが、適切なアダプターを使用すれば完璧に機能します。
JavaScript では、アプリケーションの構造と正確に一致しないサードパーティのライブラリまたは API を統合するときに、アダプター パターンを使用することがあります。アダプターは、クラスのインターフェースをクライアントが期待する別のインターフェースに変換し、統合をシームレスに行うことができます。
class OldApi { constructor() { this.data = 'Old API data'; } getData() { return this.data; } } class NewApi { fetchData() { return 'New API data'; } } class ApiAdapter { constructor(oldApi) { this.oldApi = oldApi; } fetchData() { return this.oldApi.getData(); } } const oldApi = new OldApi(); const adapter = new ApiAdapter(oldApi); console.log(adapter.fetchData()); // 'Old API data'
The Composite pattern allows you to treat individual objects and compositions of objects uniformly. It’s like Russian nesting dolls where each doll is part of a larger structure, but you can interact with them both as individual dolls and as a nested set.
This pattern is often used in scenarios where you need to manage a hierarchy of objects. For example, consider a file system where files and folders are represented as objects. A folder can contain multiple files or even other folders, and you want to treat both files and folders similarly when it comes to operations like moving, copying, or deleting.
class File { constructor(name) { this.name = name; } display() { console.log(this.name); } } class Folder { constructor(name) { this.name = name; this.children = []; } add(child) { this.children.push(child); } display() { console.log(this.name); this.children.forEach(child => child.display()); } } const file1 = new File('file1.txt'); const file2 = new File('file2.txt'); const folder = new Folder('MyFolder'); folder.add(file1); folder.add(file2); folder.display(); // Output: // MyFolder // file1.txt // file2.txt
These are just a few of the many design patterns that can make your JavaScript code more robust, maintainable, and, let’s face it, fun to write. Whether you’re building the next big app or just trying to organize your code a bit better, these patterns can be your secret weapon. So next time you’re stuck, remember: there’s probably a pattern for that!
And hey, even if your code doesn’t end up looking like a LEGO spaceship, at least it won’t be a pile of colorful chaos.
Happy coding! ?
以上がソフトウェア設計パターン: すべての優れたアプリの背後にある秘密のソースの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。