エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

Typescriptで覚えるデザインパターン

きっかけ

長くやってきたJavaから離れ、サブウェポンとしてTypescriptを仕事で使いながら覚えることに。
新しくことへの挑戦になるが、基本的な考え方が変わらないと感じた。
つまり、汎用的な考えを抑えることができれば、使う言語が変わったとしても問題はないと感じて執筆に至る。

デザインパターンとは

デザインパターンとは、「オブジェクト指向において、よく使われる設計をパターン化したもの」です。
これを適用させると、プログラムが再利用しやすく、かつ読みやすいものとなります。
デザインパターンを正しく理解するためは、オブジェクト指向の知識を持っていることが大前提

デザインパターン関連サイト

サルでもわかる 逆引きデザインパターン 第1章 はじめてのデザインパターン はじめに

デザインパターン入門 - IT専科

デザインパターン (ソフトウェア) - Wikipedia

geechs-magazine.com

ここでのデザインパターン

一番有名なGoFの23のパターンのことを指すものとする。
パターンは大別して、生成・構造・振る舞いに別れ、全て合わせて23パターン存在する。

生成

パターン名 概要
Abstract Factory 関連するAPI群のインスタンスを生成する方法を提供する。
Builder オブジェクト生成を抽象化して、オブジェクトを生成する。
Factory Method サブクラスにインスタンス生成をさせる。
Prototype インスタンスを複製する。
Singleton 生成できるインスタンスを1個に制限する。

構造

パターン名 概要
Adapter インタフェースが一致しないクラスを再利用する。
Bridge 機能と実装の階層を分離する。
Composite 再帰的なオブジェクト構造を表現する。
Decorator オブジェクトを機能を拡張するための構造を提供する。
Facade 複雑な処理を呼び出す入り口を提供して、煩雑な処理を簡略化させる。
Flyweight インスタンスで共有可能なものを共有して、生成コスト・使用メモリを抑える。
Proxy プロキシを使って、インスタンスの生成やアクセス管理する。

振る舞い

パターン名 概要
Chain of Responsibility 処理をチェーンのようにつなげて、処理を順次的に処理する。
Command 命令をオブジェクトとして処理させる。
Interpreter 構文解析結果を表現するクラスを提供する。
Iterator 複数のオブジェクトに順次アクセスする。
Mediator 複数のオブジェクトを集中管理する。
Memento オブジェクトの状態を保管して復元可能にする。
Observer オブジェクトの状態変化を通知する。
State 状態に応じて処理内容を切り替える。
Strategy アルゴリズムを入れ替えるにする。
Template Method 処理の流れを親クラスで実装し、詳細な処理をサブクラスで実装させる。
Visitor 複数のオブジェクトを監視・追加・変更する

デザインパターン

よく使うものだけ確認
暇だったら追加しておくかも

Singleton

export default class Singleton {

    private static instance: Singleton;

    /** コンストラクタ隠蔽 */
    private Singleton() {};

    public static getInstance(): Singleton {
        if(this.instance) {
            return this.instance;
        }

        this.instance = new Singleton();
        return this.instance;
    }
}

Factory Method

abstract class Creator<P extends Product> {

    abstract factoryMethod(): P;

    create(): P {
        return this.factoryMethod();
    }
}

abstract class Product {
    private name: string;
    setName(name: string) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}

class ProductG extends Product {
    private no: string;
    constructor(name: string, no: string) {
        super();
        this.setName(name);
        this.no = no;
    }
    getNo(): string {
        return this.no;
    }
}

class GCreator extends Creator<ProductG> {

    factoryMethod(): ProductG {
        return new ProductG("FREEDUM", "X10A");
    }
}

let factory = new GCreator();
let g = factory.create();
console.log(`name: ${g.getName()} no: ${g.getNo()}`);

ちなみに、この工場はフリーダムガンダムを生成する。

Strategy

ほぼStateと一緒。

class Strategy {
    strategy(name: string): () => void {
        return this.strategyArr[name];
    }

    private strategyArr: {
        [key: string]: () => void;
    } = {
        "fusiion": () => console.log("E・HERO フレア・ウィングマン"),
        "syncro": () => console.log("スターダスト・ドラゴン"),
        "xys": () => console.log("No.39 希望皇ホープ"),
        "pendulum": () => console.log("オッドアイズ・ペンデュラム・ドラゴン"),
    }
}

let strategy = new Strategy();
strategy.strategy("syncro")();