GoFデザインパターン ~Factory Methodパターン~
こちらを読みながら進める。
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (397件) を見る
Factory Methodパターンとは
Template Methodパターンではスーパークラスで処理の枠組みを決め具体的な処理は子クラスで実装したが、それをインスタンス生成に適用したのがFactory Methodパターン。Factory Methodパターンによって、インスタンス生成の枠組みとインスタンス生成の実装を分けることができる。
実装
増補改訂版Java言語で学ぶデザインパターン入門で使われてる例をGoで実装してみる。
ディレクトリ構成は以下
./4_factory_method ├── framework │ ├── creater.go │ ├── factory.go │ └── product.go ├── idcard │ ├── idcard.go │ └── idcard_factory.go └── main.go
frameworkパッケージ
package framework type Creater interface { CreateProduct(string) Product RegisterProduct(Product) } type Product interface { Use() string GetOwner() string } type Factory struct {} func (*Factory) Create(creater Creater, owner string) Product { p := creater.CreateProduct(owner) creater.RegisterProduct(p) return p }
Goで実装しようとするとImplementFactoryにFactoryを継承させることは難しいため、Factory.Create()
にCreaterインターフェースを実装したImplementFactoryを渡すことでポリモーフィズムを実現するようにした
idcardパッケージ
このパッケージがインスタンス生成の具体的な処理を担う
package idcard import ( "fmt" "github.com/saekis/go-design-pattern/4_factory_method/framework" ) type IdCard struct { owner string } func NewIdCard(owner string) framework.Product { return &IdCard{owner: owner} } func (ic *IdCard) Use() string { return fmt.Sprintf("Use %s's card", ic.owner) } func (ic *IdCard) GetOwner() string { return ic.owner } type IdCardFactory struct { owners []string } func NewIdCardFactory() framework.Creater { return &IdCardFactory{owners: []string{}} } func (*IdCardFactory) CreateProduct(owner string) framework.Product { return NewIdCard(owner) } func (factory *IdCardFactory) RegisterProduct(p framework.Product) { factory.owners = append(factory.owners, p.GetOwner()) }
IdCardFactory
構造体がFactory Methodパターンにおけるインスタンス生成の具体的な処理を実装するクラス
Main
Main実装
package main import ( "fmt" "github.com/saekis/go-design-pattern/4_factory_method/framework" "github.com/saekis/go-design-pattern/4_factory_method/idcard" ) func main() { factory := framework.Factory{} creater := idcard.NewIdCardFactory() card1 := factory.Create(creater, "たろう") card2 := factory.Create(creater, "はなこ") card3 := factory.Create(creater, "たかし") fmt.Println(card1.Use()) fmt.Println(card2.Use()) fmt.Println(card3.Use()) }
実行結果
$ go run main.go Use たろう's card Use はなこ's card Use たかし's card