Skip to content

Instantly share code, notes, and snippets.

@dustinboston
Created July 16, 2013 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustinboston/6007675 to your computer and use it in GitHub Desktop.
Save dustinboston/6007675 to your computer and use it in GitHub Desktop.
MVC where the controller is a mediator and the views are both observers and colleagues.
class List
constructor: () ->
# A list of pointers
@items = []
# Objects passed in by pointer
@objects = {}
# Returns the number of objects in the list
count: () ->
@items.length
# Returns the object at the given length
get: (index) ->
@objects[@items[index]]
# Returns the object with the given key
getByKey: (key) ->
@objects[key]
# Returns the first object in the list
first: () ->
@objects[@items[0]]
# Returns the last object in the list
last: () ->
@objects[@items[@items.length - 1]]
# Adds the argument to the list, making it the last item
append: (item, key) ->
item.__POINTER__ = key if key
pointer = item.__POINTER__
@items.push pointer
@objects[pointer] = item
# Removes the given element from the list.
remove: (item) ->
pointer = item.__POINTER__
delete @objects[pointer]
index = pointer in @items
# delete @items[index] if index isnt -1
@items.splice index, 1
# Removes the last element from the list
removeLast: () ->
@remove @last
# Removes the first element from the list
removeFirst: () ->
@remove @first
# Removes all elements from the list
removeAll: () ->
@items = []
@objects = {}
class Iterator
first: () ->
next: () ->
isDone: () ->
currentItem: () ->
class ConcreteIterator extends Iterator
constructor: (@list) ->
@current = 0
first: () ->
@current = 0
next: () ->
@current += 1
isDone: () ->
@current >= @list.count()
currentItem: () ->
throw new Error "IteratorOutOfBounds" if @isDone()
@list.get @current
class Colleague
constructor: (@mediator) ->
changed: () ->
@mediator.colleagueChanged @
class Observer extends Colleague
update: (theChangedSubject) ->
class ConcreteColleague1 extends Observer
event: () ->
@changed()
update: (theChangedSubject) ->
console.log "ConcreteColleague1 updated", theChangedSubject
class ConcreteColleague2 extends Observer
event: () ->
@changed()
update: (theChangedSubject) ->
console.log "ConcreteColleague2 updated", theChangedSubject
class Subject
constructor: () ->
@counter = 0
@observers = new List()
attach: (o) ->
o.__POINTER__ = @counter
@observers.append o
@counter += 1
detach: (o) ->
@observers.remove o
notify: () ->
i = new ConcreteIterator @observers
while not i.isDone()
i.currentItem().update @
i.next()
class ConcreteSubject extends Subject
class Mediator
constructor: () ->
@colleagues = new List()
colleagueChanged: (colleague) ->
class ConcreteMediator extends Mediator
createColleagues: () ->
@colleagues.append new ConcreteColleague1(@), 'colleague1'
@colleagues.append new ConcreteColleague2(@), 'colleague2'
# The hypothetical model below should notify its own observers.
# It should simply get configured here with the standard attach.
@subject = new ConcreteSubject()
@subject.attach @colleagues.getByKey 'colleague1'
@subject.attach @colleagues.getByKey 'colleague2'
@subject.notify()
@colleagues.getByKey('colleague1').event()
colleagueChanged: (colleague) ->
if colleague instanceof ConcreteColleague1
console.log 'ConcreteColleague1 changed'
else if colleague instanceof ConcreteColleague2
console.log 'ConcreteColleague2 changed'
mediator = new ConcreteMediator()
mediator.createColleagues()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment