Interface Composition
Demonstrating Interface Composition in Go
One cool feature of Go is that it lets you compose interfaces using other interfaces. The prototypical example of this is the ReadWriter, which is composed of the Reader interface and the Writer interface.
Below is an example of a toy program that defines a UserStorer interface and an ItemStorer interface, then a Storer interface that is composed of these interfaces
Define User Stuff
package main
import (
"encoding/json"
"fmt"
)
//create type
type User struct {
Name string
Age int
}
//create interface
type UserStorer interface {
AddUser(users []*User, user *User) []*User
}
//define an empty struct that will implement interface
type ustore struct{}
//constructor
func NewUserStore() UserStorer {
return &ustore{}
}
func (us ustore) AddUser(users []*User, user *User) []*User {
users = append(users, user)
return users
}Define Item Stuff
//define type
type Item struct {
Name string
Usage string
}
//define interface
type ItemStorer interface {
AddItem(items []*Item, item *Item) []*Item
}
//define empty struct that will implement interface
type istore struct{}
//define constructor
func NewItemStore() ItemStorer {
return &istore{}
}
//define add method
func (is istore) AddItem(items []*Item, item *Item) []*Item {
items = append(items, item)
return items
}Define Storer Stuff
type Storer interface {
UserStorer
ItemStorer
}
type myStore struct {
UserStorer
ItemStorer
}
func NewStorer(us UserStorer, is ItemStorer) Storer {
s := &myStore{
UserStorer: us,
ItemStorer: is,
}
return s
}Create Simple Program
func main() {
us := NewUserStore()
is := NewItemStore()
s := NewStorer(us, is)
var items []*Item
var users []*User
u := &User{
Name: "Eric",
Age: 34,
}
i := &Item{
Name: "Phone",
Usage: "texting",
}
items = s.AddItem(items, i)
users = s.AddUser(users, u)
//embed to json
ji, _ := json.Marshal(items)
ju, _ := json.Marshal(users)
//print out results
fmt.Println(string(ji))
fmt.Println(string(ju))
}