Skip to content

Instantly share code, notes, and snippets.

@benjic
Last active September 9, 2015 04:40
Show Gist options
  • Save benjic/0523dd9b427815f5c26d to your computer and use it in GitHub Desktop.
Save benjic/0523dd9b427815f5c26d to your computer and use it in GitHub Desktop.
A simple implementation of the Adapter Pattern.
package widgets
import "fmt"
// A IBiz is any type that implements the Baz function
type IBiz interface {
Baz()
}
// A Biz is our non client supported type
type Biz struct{}
// Baz implements the IBiz interface
func (b Biz) Baz() { fmt.Println("Bizbaz") }
// A SuperBiz is a different type that also implements the IBiz interface
type SuperBiz struct{}
// Baz is requried for the IBiz interface but this implementation is super
// powerful.
func (b SuperBiz) Baz() { fmt.Println("Super BIZBAZ") }
// A ClassClientToBizAdapter is the first type of adapter that ineheriets from
// the client interface allowing us to adapt to the expected function calls.
type ClassClientToBizAdapter struct {
Foo // We embed(inheriet) the client type
Biz // As well as the adaptee type
}
// Bar overrideds the embeded function so that we can use indirection to call
// the baz function.
func (a ClassClientToBizAdapter) Bar() {
a.Baz()
}
// An ObjectClientToBizAdapter uses the encapsulation/composition adapter mechanism
// to adapt any type that implements the IBiz interface.
type ObjectClientToBizAdapter struct {
biz IBiz
}
// NewObjectClientToBizAdapter factory function is needed since our encapsulated
// biz field is private.
func NewObjectClientToBizAdapter(biz IBiz) ObjectClientToBizAdapter {
return ObjectClientToBizAdapter{biz: biz}
}
// Bar is needed to implement the Foo interface allowing the adapter to direct
// client calls to Bar to the adaptee encapsulated by the adapter. Since we can
// use anything that implements IBiz this adapter can be resused.
func (a ObjectClientToBizAdapter) Bar() { a.biz.Baz() }
package widgets
import "fmt"
// An IFoo describes the interface our client consumes. In this instance the
// client will call Bar()
type IFoo interface {
Bar()
}
// A Foo is a type used by the client
type Foo struct{}
// Bar is the client function that is meant to be adapted.
func (f Foo) Bar() { fmt.Println("Foobar") }
package main
import w "./widgets"
func main() {
biz := w.Biz{}
superBiz := w.SuperBiz{}
// Client expects to consume foos
// create a array of foo and adapters
foos := []w.IFoo{
w.Foo{}, // The Foo type in ernest
w.NewObjectClientToBizAdapter(biz),
w.NewObjectClientToBizAdapter(superBiz),
w.ClassClientToBizAdapter{},
}
// Iterate over collection of foos
for _, foo := range foos {
// Since Foo and our adapters implement the IFoo interface they work in the
// client.
foo.Bar()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment