I'm trying to use builder patterns (borrowed from Java) to allow structs to implement interfaces. For example, I would ideally like this code pattern:
package main
import "fmt"
type Oner interface {
One() int
}
type Twoer interface {
Two() int
}
func main() {
s := NewObject().
WithOne(1).
Build()
_, ok := s.(Oner)
fmt.Println(ok) // Prints true
_, ok = s.(Twoer)
fmt.Println(ok) // Prints false
t := NewObject().
WithOne(1).
WithTwo(2).
Build()
_, ok = t.(Oner)
fmt.Println(ok) // Prints true
_, ok = t.(Twoer)
fmt.Println(ok) // Prints true
}
As you could see, the definition of the builder determines what interfaces s
and t
implement.
How would one write the function definition of the builder NewObject()
so the Build()
method returns a struct which can (possibly) implement a Oner
and Twoer
?
Edit:
Here's some clarification on how it's going to be used. I'm constructing a library barring certain structs from being passed into functions if they violate the type safety. For example:
type Oner interface {
One() int
}
type OneAndTwoer interface {
Oner
Two() int
}
type Library interface {
DoSomethingWithOner(Oner)
DoSomethingWithOneAndTwoer(Twoer)
}
Though we can define a function which always constructs a OneAndTwoer
, my constraints are whenever we construct a OneAndTwoer
, this takes a lot longer time than just constructing a Oner
func NewOneAndTwoer() OneAndTwoer {
// Do some really really complicated logic which takes a lot of time
}
func NewOner() Oner {
// Do simple logic
}
You could imagine how if we have a Threer
, Fourer
, etc, this becomes extremely unwieldly, and we have to construct constructors for all possible permutations of attributes.
This is where builder patterns come in handy. Assuming the calculations for One
, Two
, etc are independent of each other, we can pick and choose which interface we want to create.