こんにちは、KOUKIです。
この記事では、デザインパターンの一つであるBuilderパターンについて、紹介しています。
今回は、インスタンスの生成なしで、開発者が特定の機能を利用する方法を学びましょう。
シチュエーション
ある開発者が、Emailの送信機能を実装したとします。
1 2 3 4 5 6 7 8 9 10 11 |
package main import "fmt" type email struct { from, to, subject, body string } func sendMail(email *email) { fmt.Println(email) } |
このsendMail関数を別の開発者が利用するとき、インスタンスを生成してからそれをパラメータとして渡すと思います。
1 2 3 4 5 6 7 8 9 10 11 |
func main() { // インスタンスを生成 e := email{ from: "selfnote@com.co.jp", to: "selfnote2@com.co.jp", subject: "Builder Pattern", body: "Would you like to learn builder pattern?", } // パラメータとして渡す sendMail(&e) } |
1 2 |
$ go run main.go &{selfnote@com.co.jp selfnote2@com.co.jp Builder Pattern Would you like to learn builder pattern?} |
しかし、Builderパターンを利用するとインスタンスを生成しなくても、sendMail関数を利用できる面白い実装が行えます。
Builderパターン Parameterの実装
早速、実装していきましょう。ちなみに、今回はコンストラクタを実装しません。
Builder構造体を作成
最初に、Building(建築)する対象を決めます。今回は、Emailですね。
1 2 3 |
type EmailBuilder struct { email email } |
パラメータ設定メソッドの実装
次に、パラメータを設定するメソッドを定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
func (b *EmailBuilder) From(from string) *EmailBuilder { b.email.from = from return b } func (b *EmailBuilder) To(to string) *EmailBuilder { b.email.to = to return b } func (b *EmailBuilder) Subject(subject string) *EmailBuilder { b.email.subject = subject return b } func (b *EmailBuilder) Body(body string) *EmailBuilder { b.email.body = body return b } |
ポインタ付きのEmailBuilderを戻り値として、定義しておきましょう。
ビルド関数の定義
次に、ビルド関数を定義します。
1 |
type build func(*EmailBuilder) |
このビルド関数は、次のように利用します。
1 2 3 4 5 6 7 8 |
// Public用のSendEmail func SendEmail(action build) { // インスタンス化 builder := EmailBuilder{} // パラメータ設定 action(&builder) sendMail(&builder.email) } |
使ってみる
それでは、早速使ってみましょう。
1 2 3 4 5 6 7 8 |
func main() { SendEmail(func(b *EmailBuilder) { b.From("selfnote@com.co.jp") b.To("selfnote2@com.co.jp") b.Subject("Builder Pattern") b.Body("Would you like to learn builder pattern?") }) } |
1 2 |
$ go run main.go &{selfnote@com.co.jp selfnote2@com.co.jp Builder Pattern Would you like to learn builder pattern?} |
SendEmail関数には、パラメータとして関数が必要なので、無名関数を渡しました。
注目していただきたいのが、利用者側ではインスタンスを生成していないというところです。
こんな感じでも実装可能なので、とても面白いと思います^^
次回
次回は、BuilderパターンのFunctional Builderバージョンを学びます。
Go言語まとめ
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
package main import "fmt" type email struct { from, to, subject, body string } func sendMail(email *email) { fmt.Println(email) } type EmailBuilder struct { email email } func (b *EmailBuilder) From(from string) *EmailBuilder { b.email.from = from return b } func (b *EmailBuilder) To(to string) *EmailBuilder { b.email.to = to return b } func (b *EmailBuilder) Subject(subject string) *EmailBuilder { b.email.subject = subject return b } func (b *EmailBuilder) Body(body string) *EmailBuilder { b.email.body = body return b } type build func(*EmailBuilder) // Public用のSendEmail func SendEmail(action build) { // インスタンス化 builder := EmailBuilder{} // パラメータ設定 action(&builder) sendMail(&builder.email) } func main() { SendEmail(func(b *EmailBuilder) { b.From("selfnote@com.co.jp") b.To("selfnote2@com.co.jp") b.Subject("Builder Pattern") b.Body("Would you like to learn builder pattern?") }) } |
コメントを残す
コメントを投稿するにはログインしてください。