Skip to content

Instantly share code, notes, and snippets.

@lucasrpb
Last active December 16, 2016 21:04
Show Gist options
  • Save lucasrpb/4cee3628290edef8ea13cc5fb9b0a17d to your computer and use it in GitHub Desktop.
Save lucasrpb/4cee3628290edef8ea13cc5fb9b0a17d to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math"
"time"
)
type Receiver interface {
Receive(data interface{})
}
type Sender interface {
Send(data interface{}) error
}
type Worker interface {
Receiver
Sender
}
/**
* Implements default methods!
*
*/
type Actor struct {
// Similar to OO's inheritance model
Worker
Name string
Mailbox chan interface{}
}
/**
* Default behavior
*/
func(actor *Actor) Send(data interface{}) error {
fmt.Println("sending from [Actor]:", data)
actor.Mailbox <- data
return nil
}
func(actor *Actor) Receive(data interface{}){
fmt.Println("received", data, "in [Actor]")
}
func(actor *Actor) handle(){
go func(){
for {
data, ok := <-actor.Mailbox; if !ok {
return
}
/**
* This is where Go's paradigm shines! If we don't override Receive in ConcreteWorker,
* the Actor's Receive method is called :)
*
* Try to remove the comment delimiters in ConcreteWorker to see what happens
*/
actor.Worker.Receive(data)
}
}()
}
func(actor *Actor) Stop(){
close(actor.Mailbox)
}
type ConcreteWorker struct {
// Composition ! Similar to inheritance in OO's paradigm
Actor
}
/*func(actor *ConcreteWorker) Receive(data interface{}) {
switch data.(type) {
case string: {
fmt.Println("RECEIVED STRING", data)
}
default: {
fmt.Println("I dont know :(")
}
}
}*/
/*
* Produces a new standard actor wrapping the desired behavior :)
* This is awesome! This is where composition is better than inheritance :P
*/
func NewActor(worker Worker, name string) *Actor {
actor := Actor{
Worker: worker,
Name: "A",
Mailbox: make(chan interface{}, math.MaxInt8),
}
// Waits for messages on the channel...
actor.handle()
return &actor
}
func main(){
actor := NewActor(&ConcreteWorker{}, "a")
actor.Send("Ping")
// Waits some time to be able to see something :P
time.Sleep(time.Second*1)
actor.Stop()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment