ちゃんなるぶろぐ

エンジニア5年生🧑‍💻 オライリーとにらめっこする毎日。

【10分でわかる👉】TypeScriptでDesign Pattern〜Command Pattern〜

どうも、ちゃんなるです!

今回は、Command Patternを紹介します🖐️

概要

Command Patternは、オブジェクト指向プログラミングにおいて、操作をオブジェクトとしてカプセル化することで、呼び出し側実行側分離します。

これにより、コードの拡張性や再利用性が向上し、メンテナンスが容易になります。

今回示すプログラムの設計

オンラインショッピングサイトで、商品の追加や削除といった操作を行うプログラムを設計してみます👍

Command Patternを用いて、これらの操作を簡単に実装・拡張できるようにしましょう🖐️

クラス図

サンプルコードのクラス図:Mermaid Live Editorで作成

クラス名 役割
Product 商品を表現する
Invoker コマンドの実行を行う
Command コマンドのインターフェース
AddProductCommand 商品追加のコマンド
RemoveProductCommand 商品削除のコマンド
ProductManager 商品の管理を行う

サンプルコード

class Product {
    constructor(public name: string) {}
}
interface Command {
    Execute(): void;
}
class AddProductCommand implements Command {
    constructor(private productManager: ProductManager, private product: Product) {}

    Execute(): void {
        this.productManager.AddProduct(this.product);
    }
}
class RemoveProductCommand implements Command {
    constructor(private productManager: ProductManager, private product: Product) {}

    Execute(): void {
        this.productManager.RemoveProduct(this.product);
    }
}
class ProductManager {
    private products: Product[] = [];

    AddProduct(product: Product): void {
        this.products.push(product);
        console.log(`Product added: ${product.name}`);
    }

    RemoveProduct(product: Product): void {
        const index = this.products.indexOf(product);
        if (index > -1) {
            this.products.splice(index, 1);
            console.log(`Product removed: ${product.name}`);
        }
    }
}
class Invoker {
    ExecuteCommand(command: Command): void {
        command.Execute();
    }
}

では、実際に使ってみましょう🖐️

const productManager = new ProductManager();
const invoker = new Invoker();

const product1 = new Product('Apple');
const product2 = new Product('Banana');

const addProductCommand1 = new AddProductCommand(productManager, product1);
const addProductCommand2 = new AddProductCommand(productManager, product2);

const removeProductCommand1 = new RemoveProductCommand(productManager, product1);
// 商品の追加
invoker.ExecuteCommand(addProductCommand1);
invoker.ExecuteCommand(addProductCommand2);
// 商品の削除
invoker.ExecuteCommand(removeProductCommand1);

Command Patternの使い道

  • 履歴機能を追加する際
  • アンドゥやリドゥ機能を実装する際
  • オブジェクトの状態を変更する操作をキューイングする際

組み合わせられるデザインパターン

  • Composite Pattern: 複数のコマンドを一つのコマンドとしてまとめることができます。

chan-naru.hatenablog.com

  • Memento Pattern: コマンド実行前後のオブジェクトの状態を保存・復元するのに役立ちます。

chan-naru.hatenablog.com

  • Observer Pattern: コマンドの実行に伴って関連オブジェクトに通知が送れます。

chan-naru.hatenablog.com

まとめ

Command Patternの基本概念と利点を、具体的なシナリオとしてオンラインショッピングサイトでの商品の追加や削除の操作を例に紹介しました。

Command Patternは、コードの拡張性や再利用性を向上させ、メンテナンスを容易にするための強力なデザインパターンです。

是非、今回の記事を参考に、プロジェクトでのCommand Patternの活用・導入を検討してみてください👍

参考文献

www.oreilly.com

en.wikipedia.org