Created
July 16, 2013 10:46
-
-
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.
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
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