君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

早とちりプログラマの失敗から学ぶデザインパターン(Factory Method:適用後)

f:id:karoten512:20171213011506p:plain

このシリーズについて

このシリーズは

  • 後先のことをなにも考えずに実装してしまう『早とちりプログラマ

  • すぐに仕様変更を加える『後出し上司』

のという魅力的な2人から、

デザインパターンの有用さを学んでいこうという素敵な企画です。

(早とちりプログラマのモデルは私です。。。)

要件

上司「コンサートでピアノが聴けるようにしてよ」

わたし「わっかりました〜!!!」

わたし「ピアノ以外もきっと対応してくれっていわれそうだな」

わたし「さて、どうするか。。。」

いろんな楽器に対応できるようポリモーフィズムを用いる

ポリモーフィズムは継承によるものとインターフェースによるものがありますが、

今回はインターフェースで実装します。

演奏できるというインターフェース

interface Playable {
  play(): void;
}

ピアノクラス

class Piano implements Playable
{
    public play(): void
    {
        console.log('ポロンポロン');
    }
}

コンサートクラス

class Concert
{
    private instrument: Playable;
    
    constructor()
    {
        this.instrument = new Piano();
    }
    
    public start(): void
    {
        this.instrument.play();
    }
}

Factory Methodを適用

わたし「このままだとConcertがPianoに依存しているから、

それをなんとかしたいな。。。Factory Method使ってみるか」

楽器生成クラス

class InstrumentFactory
{
    static create(instrumentCode: string): Playable {
        if (instrumentCode === 'piano') {
            return new Piano();
        }
    }
}

コンサートクラス修正

class Concert
{
    private instrument: Playable;
    
    constructor()
    {
        this.instrument = InstrumentFactory.create('piano');
    }
    
    public start(): void
    {
        this.instrument.play();
    }
}

わたし「よし、これでConcertクラスから特定のクラスのnewが消えたな」

仕様変更

上司「クライアントがさ、やっぱりピアノじゃなくてギターじゃないとダメだって」

修正

ギタークラス

class Guitar implements Playable
{
    public play()
    {
        console.log('ジャーン');        
    }
}

楽器生成クラス追加

class InstrumentFactory
{
    static create(instrumentCode: string): Playable {
        if (instrumentCode === 'piano') {
            return new Piano();
        } else if (instrumentCode === 'guiltar') {
            return new Guitar();
        }
    }
}

コンサートクラス修正

class Concert
{
    private instrument: Playable;
    
    constructor()
    {
        this.instrument = InstrumentFactory.create('guitar'); // 修正
    }
    
    public start(): void
    {
        this.instrument.play();
    }
}

結果

呼び出す側の修正は、 楽器名を変えるだけでよくなりました。

デザインパターンを使用すると、記述量は増えますが、

既存のソースコードの書き直しが劇的に減ります(3箇所→1箇所)