Factory Method
インスタンスの作り方をスーパークラスで抽象的に定義しておき,その具体的な実装を継承したサブクラスで行う. Factory MethodはTemplate Methodをインスタンス生成に適用したパターンであると考えることができる.
クラス構造
templateパッケージの中に,抽象クラスとして,ChefクラスとDishクラスがある.これらのクラスには,抽象メソッドが含まれるので,これらのクラスを継承するサブクラスでは,抽象メソッドを実装する必要がある.
このような定義によって,スーパークラスでは,共通するメソッドなどの骨組みを作り,それをサブクラスで具体的に実装することができる.これによって,外部から見て,メソッドが共通であるので,メソッドを呼ぶという手続きは同じでありながら,サブクラスで,各々の特徴となる具体的な処理内容を定義することができる.
ソースコード
調理師を意味するChefクラスは,抽象クラスとして定義されており,「Dish」を返す「cooking」メソッドを持つ.また,「providing」メソッドは,料理を客に出すときの出し方を定義している.「working」メソッドは料理を作って,それを出すという,一連のメソッドを実行する.
package template; public abstract class Chef { protected abstract Dish cooking(String order); protected abstract void providing(Dish dish); public void working(String order){ Dish dish = cooking(order); providing(dish); } }
調理師が生成する料理を抽象クラスとして,Dishクラスを定義する.Dishクラスでは,料理の完了をお知らせするためのメソッド「introduction」メソッドが抽象メソッドとして定義されているため,サブクラスで実装する必要がある.setDishNameとgetDishNameにて,料理の名前を設定,応答する.
package template; public abstract class Dish{ private String dishName; public String getDishName(){ return dishName; } public void setDishName(String order){ dishName = order; } protected abstract String introduction(); }
抽象クラスとして,調理師クラスと料理クラスを定義する.これらを継承したサブクラスにて,抽象メソッドを実装することで,抽象的に動作を定義したところに,具体化したクラスがあてはまるようになる.
以下に,寿司職人が寿司を作る場合を想定して実装したクラスを示す.寿司職人は「料理」を返り値とする「調理する」メソッドでは,寿司を作ってそれを返す.返り値の型が「料理」クラスではなく「寿司」クラスであるが,「寿司」クラスは「料理」クラスを継承しているため,スーパークラスで定義されている値と合致しているので,問題ない.
package worker; import template.Chef; import template.Dish; public class SushiShokunin extends Chef{ protected Dish cooking(String order){ return new Sushi(order); } protected void providing(Dish dish){ System.out.println(dish.introduction() + "食ってくんな!"); } }
「料理」クラスを継承して「寿司」クラスを作る.
package worker; import template.Chef; import template.Dish; public class Sushi extends Dish{ public Sushi(String sushiType) { setDishName(sushiType); } protected String introduction(){ return getDishName() + "一丁!"; } }
実装した結果を用いて,実行するプログラムを与える.
import template.Chef; import worker.SushiShokunin; public class Main { public static void main(String args[]) { ChefsushiShokunin = new SushiShokunin(); sushiShokunin.working("トロ"); sushiShokunin.working("マグロ"); } }
実行した時の出力結果を以下に示す.
トロ一丁!食ってくんな! マグロ一丁!食ってくんな!
演習
(1)追加
寿司職人クラスと寿司クラスの場合と同様に,パティシエクラスを追加して,パティシエがつくるケーキクラスを作る. また,Mainクラスにて,パティシエをインスタンス化し,パティシエにケーキ類のオーダーをして,オーダーしたケーキ類が返ってくることを確認する.
(2)FactoryMethod全体を作る
家電を作る工場と,家電を抽象クラスとして定義し,それらを継承して,テレビ工場クラスとテレビクラス,冷蔵庫工場クラスと冷蔵庫を作る. さらに,テレビ工場がテレビを作って出荷する手順,冷蔵庫工場が冷蔵庫を作る手順を試す.
さらに,作成したクラスのクラス図を作成する.
提出
内容:FactoryMethodパターンの作成締切日時:1月31日17:00
提出先:WebClass
課題:FactoryMethod パターンの演習「(2)FactoryMethod全体を作る」の課題