Skip to content

Instantly share code, notes, and snippets.

@jarrodhroberson
Last active May 25, 2023 15:50
Show Gist options
  • Save jarrodhroberson/4075264e19fdd4749cb1f60329f0b0d4 to your computer and use it in GitHub Desktop.
Save jarrodhroberson/4075264e19fdd4749cb1f60329f0b0d4 to your computer and use it in GitHub Desktop.
typesafebuilder.gotype safe builder in GoType Safe Builder in Go
/*
* It becomes painfully obvious why this pattern is NOT embraced by the Go community.
* Just to be painfully clear, DO NOT DO THIS!
*/
package main
import (
"fmt"
)
type Person struct {
FirstName string
LastName string
EmailAddress string
}
type PersonBuilderFirstName interface {
FirstName(string) PersonBuilderLastName
}
type PersonBuilderLastName interface {
LastName(string) PersonBuilderEmailAddress
}
type PersonBuilderEmailAddress interface {
EmailAddress(string) Person
}
func PersonBuilder() PersonBuilderFirstName {
return &personBuilder{
firstName: "",
lastName: "",
emailAddress: "",
}
}
type personBuilder struct {
firstName string
lastName string
emailAddress string
}
func (pb *personBuilder) FirstName(firstName string) PersonBuilderLastName {
//TODO: validate firstName to fail fast
pb.firstName = firstName
return pb
}
func (pb *personBuilder) LastName(lastName string) PersonBuilderEmailAddress {
//TODO: validate lastName fail fast
pb.lastName = lastName
return pb
}
func (pb *personBuilder) EmailAddress(emailAddress string) Person {
//TODO: validate emailAddress fail fast
pb.emailAddress = emailAddress
//TODO: or validate them all in one giant block here and lose context of where the invalid data came from
return Person{
FirstName: pb.firstName,
LastName: pb.lastName,
EmailAddress: pb.emailAddress,
}
}
func main() {
pb := PersonBuilder()
person := pb.FirstName("John").LastName("Doe").EmailAddress("[email protected]")
fmt.Println(person)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment