Created
October 17, 2016 15:59
-
-
Save anonymous/68c3b072538ec48c2667f7db276e781b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
func main() { | |
// Simple illustrative function | |
a := NewA() | |
a.Formatter.FormatText("Default behaviour with struct A") | |
a.Formatter.Enable = true | |
a.Formatter.FormatText("Stateful behaviour with struct A") | |
b := NewB().Formatter | |
b.FormatText("Default behaviour with struct B") | |
b.Enable = true | |
b.FormatText("Stateful behaviour with struct B") | |
} | |
type MHostInterface interface { | |
// The methods of the parent that will be acted on by M | |
Display(string) | |
} | |
type M struct { | |
// Link to the struct in which M is composed into and must act upon | |
host MHostInterface | |
// Some internal state that modifies behaviour | |
Enable bool | |
} | |
func NewM(obj MHostInterface) *M { | |
// Create an instance of the behaviour M linked to a specific host to act upon | |
if obj == nil { | |
panic("Cannot make a new M with a nil host") | |
} | |
m := M{host: obj} | |
return &m | |
} | |
func (m *M) FormatText(s string) { | |
// Provide some re-usable functionality which uses / manipulates whatever host is using M | |
if m.Enable { | |
m.host.Display(fmt.Sprintf("Mixin M has formatted text '%s'", s)) | |
} | |
} | |
// A uses behaviour M | |
type A struct { | |
// M's exported methods are usable by both A and users of A | |
Formatter *M | |
} | |
func NewA() *A { | |
// Add behaviour M when creating an instance of the struct | |
var a A | |
a = A{Formatter: NewM(&a)} | |
return &a | |
} | |
func (a *A) Display(s string) { | |
// Some A specific code that is exported and usable by M | |
fmt.Printf("A: %s\n", s) | |
} | |
// B uses behaviour M | |
type B struct { | |
Formatter *M | |
} | |
func NewB() *B { | |
// Add behaviour M when creating an instance of the struct | |
var b B | |
b = B{Formatter: NewM(&b)} | |
return &b | |
} | |
func (b *B) Display(s string) { | |
// Some B specific code that is exported and usable by M | |
fmt.Printf("B: %s\n", s) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment