#Factory Method
目次
Abstract Factoryパターンの具象工場クラスの部分のみが本パターンに該当すると理解しています。
##目的
オブジェクトを生成するときのインタフェースだけを規定して、実際にどのクラスをインスタンス化するかはサブクラスが決めるようにする。Factory Methodパターンは、インスタンス化をサブクラスに任せる。
##構成要素
・Product 生成される部品の抽象クラス
・ConcreteProduct 生成される部品
・Creator 部品製造工場の抽象クラス
・ConcreteCreator 部品製造工場
##実装
プロスポーツ選手に主催者が宣誓してもらうようなプログラムを実装します。宣誓を行う代表選手はそれぞれのスポーツ連盟により派遣されます。
###Product 生成される部品の抽象クラス
プロスポーツ選手抽象クラス
package factorymethod
abstract class ProfessionalAthlete(type: Type) {
enum class Type(val value: String) {
Soccer("サッカー"),
BaseBall("野球")
}
val myType = type
abstract fun athletesOath()
}
###ConcreteProduct 生成される部品
プロサッカー選手具象クラス
package factorymethod
class ProfessionalSoccerAthlete(name: String): ProfessionalAthlete(Type.Soccer) {
private val name = name
override fun athletesOath() {
println("宣誓!私は" + name + "です。プロ【" + myType.value + "】選手としてサッカーボールを使い正々堂々プレーします!")
}
}
プロ野球選手具象クラス
package factorymethod
class ProfessionalBaseBallAthlete(name: String): ProfessionalAthlete(Type.BaseBall) {
private val name = name
override fun athletesOath() {
println("宣誓!私は" + name + "です。プロ【" + myType.value + "】選手としてバットと野球ボールを使い正々堂々プレーします!")
}
}
以上で選手(product)が実装できました。次は選手(product)を派遣(create)するスポーツ連盟(factory)を実装していきます。
###Creator 部品製造工場の抽象クラス
スポーツ連盟抽象クラス
package factorymethod
abstract class SportsFederation {
fun getAthlete(): ProfessionalAthlete {
return dispatchRepresentativeAthlete()
}
protected abstract fun dispatchRepresentativeAthlete(): ProfessionalAthlete
}
###ConcreteCreator 部品製造工場
サッカー連盟具象クラス
package factorymethod
class SoccerFederation: SportsFederation() {
override fun dispatchRepresentativeAthlete(): ProfessionalAthlete {
return ProfessionalSoccerAthlete("サカ田 代表太郎")
}
}
野球連盟具象クラス
package factorymethod
class BaseBallFederation: SportsFederation() {
override fun dispatchRepresentativeAthlete(): ProfessionalAthlete {
return ProfessionalBaseBallAthlete("野球本 キャプテン男")
}
}
最後に各スポーツ連盟(factory)に代表選手(product)を要求し、宣誓させる主催者を実装します。
###使用者
主催者クラス
package factorymethod
class Organizer {
init {
var athleteList: MutableList<ProfessionalAthlete> = mutableListOf()
// それぞれのスポーツ連盟から代表選手を派遣してもらう
// サッカー連盟から代表選手取得
athleteList.add(SoccerFederation().getAthlete())
// 野球連盟から代表選手取得
athleteList.add(BaseBallFederation().getAthlete())
// 宣誓してもらう
for (athlete in athleteList) {
athlete.athletesOath()
}
}
}
以上で生成しなければならないオブジェクトのクラスを事前に知ることができない場合に用いることができるパターンができました。ような気がします。
###出力結果
[output]
宣誓!私はサカ田 代表太郎です。プロ【サッカー】選手としてサッカーボールを使い正々堂々プレーします!
宣誓!私は野球本 キャプテン男です。プロ【野球】選手としてバットと野球ボールを使い正々堂々プレーします!