datchの日記

気がついたら社会人。気になる技術的なことについて少しずつ書いていけたらと思っております。

【デザインパターン】シンプルファクトリーパターン

今回はファクトリーパターンについて触れていきます。
この章は非常に長く、複数のファクトリーパターンについて取り扱っているので一つ一つ取り上げていきたいと思います。
今回は、そのなかでも最初に紹介される『SimpleFactory』パターンです。


参考書



さらっと読める「OREILLY Head First デザインパターン」を参考にしながら書いています。
しばらくはこいつを参考にデザインパターンについて書いていくよ!

SimpleFactoryパターンって何ですか?



SimpleFactoryパターンはデザインパターンのFactoryパターンの中でも名前の通り、非常にシンプルな作りになっています。
非常に単純なパターンですが、ファクトリーパターンを理解する上での基礎になります
ファクトリーパターンは多態性によってサブクラスを動的に変化させる部分を抜き出して、変更する部分を取り出すデザインパターンです。

身近で簡単な使用例



参考書のケースを参考にして説明を行っていきます。
とあるピザ屋の話。

複数の種類のピザを名前から作成出来る関数を作りました。

Pizza orderPizza(String type){
    Pizza pizza;

    if(type.equals("チーズ")){ pizza = new CheesePizza();}
    else if(type.equals("ギリシャ")){ pizza - new CreekPizza();}
    else if(type.equals("ペパロニ")){ pizza = new PepperoniPizza(); }

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
}

しかし、競争圧力が高まり、さらにピザの種類を追加します。

Pizza orderPizza(String type){
    Pizza pizza;

    if(type.equals("チーズ")){ pizza = new CheesePizza();}
    // else if(type.equals("ギリシャ")){ pizza - new CreekPizza();} // ギリシャピザは売れなかったのでメニューから消します。
    else if(type.equals("ペパロニ")){ pizza = new PepperoniPizza(); }
    else if(type.equals("クラム")){ pizza = new ClamPizza(); }
    else if(type.equals("野菜")){ pizza = new VeggiePizza(); }

    // 以下なh全てのピザに対して同様の処理を行います
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
}

さて、このままでは商品の追加・変更が加わる度に、コードを追加・変更しなければなりません。
これでは orderPizza() は非常にコードが頻繁に変化する部分と、下の変化しない部分が共有してしまいます。

ここでSimpleFactoryパターンの出番です!
このコードが依存しているピザの生成についてデザインパターンを使って、このコードの変更を最小にします。

SimpleFactoryの書き方


以下にSimpleFactoryのクラスを記述します。

public class SimplePizzaFactory{
    public Pizza createPizza(String type){
        Pizza pizza = null;

        if(type.equals("チーズ")){ pizza = new CheesePizza();}
        else if(type.equals("ペパロニ")){ pizza = new PepperoniPizza(); }
        else if(type.equals("クラム")){ pizza = new ClamPizza(); }
        else if(type.equals("野菜")){ pizza = new VeggiePizza(); }

        return pizza;
    }
}

このクラスを先ほどの関数に入れ込みます。

Pizza orderPizza(String type){
    Pizza pizza;

    SimplePizzaFactory factory = new SimplePizzaFactory();
    Pizza pizza = factory.cratePizza(type);

    // 以下なh全てのピザに対して同様の処理を行います
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
}

これによりコードの変更をSimplePizzaFactoryに隔離することが出来ました。

最後に



え、もうこれでおしまい?
そうです、SimpeFactoryはこれでおしまいです。
次のFactoryMethodパターンではこれを拡張したものになるので、この流れを理解することでより早く理解をすることが出来ます。
今のままではFactoryパターンの強みを理解するのが難しいと思いますが、進むに連れて徐々にこのパターンの良さに気づくことが出来るでしょう。

ではでは