Creational Design Pattern: Builder – Part 3

Pada modul ini kita akan membahas bagaimana memastikan user menggunaan builder, tidak mengakses langsung object yang kita buat.

Salah satu caranya adalah dengan “menyembunyikan” object tersebut.

Contoh kasus, API untuk mengirim email, agar user tidak langsung menyentuh struct email, kita buat EmailBuilder. Perhatikan struct email didefinisikan dengan huruf kecil agar tidak dapat diakses diluar package.

Karena kita tidak ingin user mengakses object email, pendekatan yang dilakukan adalah dengan builder parameter, yaitu function yang menerima argument builder.

Lihat code dibawah cara untuk membuat builder parameter. func SendEmail adalah fungsi yang akan diakses user dengan parameter EmailVuilder.

type build func(*EmailBuilder)
func SendEmail(action build) {
	builder := EmailBuilder{}
	action(&builder)
	sendMailImpl(&builder.email)
}

Saat digunakan oleh user, mereka akan melakukan building object email melalui EmailBuilder. Tidak mengakses object yang disembunyikan dalam package

SendEmail(func(b *EmailBuilder) {
	b.From("foo@bar.com").
		To("bar@baz.com").
		Subject("Meeting").
		Body("Hello, do you want to meet?")
})

Berikut isi lengkap kode cara menggunakan Builder Parameter.

package main

import "strings"

//definisikan object email dengan lowercase agar tidak bisa diakses diluar package
type email struct {
	from, to, subject, body string
}

//Builder yang akan diakses oleh user
type EmailBuilder struct {
	email email
}

func (b *EmailBuilder) From(from string) *EmailBuilder {
        //contoh validasi sederhana
	if !strings.Contains(from, "@") {
		panic("email should contain @")
	}
	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
}

func sendMailImpl(email *email) {
	// fungsi ini tidak akan diakses oleh user
}


//fungsi send email yang akan diakses user
type build func(*EmailBuilder)
func SendEmail(action build) {
	builder := EmailBuilder{}
	action(&builder)
	sendMailImpl(&builder.email)
}

func main() {
	SendEmail(func(b *EmailBuilder) {
		b.From("foo@bar.com").
			To("bar@baz.com").
			Subject("Meeting").
			Body("Hello, do you want to meet?")
	})
}
Sharing is caring:

Leave a Comment