Skip to content

Instantly share code, notes, and snippets.

@todashuta
Last active August 29, 2015 14:06
Show Gist options
  • Select an option

  • Save todashuta/d5adff0e97c9db79eb59 to your computer and use it in GitHub Desktop.

Select an option

Save todashuta/d5adff0e97c9db79eb59 to your computer and use it in GitHub Desktop.
Vim script で Observer pattern を書いてみた
" Vim script で Observer pattern を書いてみた
" 参考URL: http://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
function! s:listenerNew(name, subject) dict
let this = deepcopy(self)
let this.name = a:name
call a:subject.register(this)
return this
endfunction
function! s:update(event) dict
echo self.name . ' received event ' . a:event
endfunction
let s:Listener = {
\ 'name': '',
\ 'new': function('s:listenerNew'),
\ 'update': function('s:update'),
\ }
function! s:subjectNew() dict
let this = deepcopy(self)
let this.listeners = []
return this
endfunction
function! s:register(listener) dict
call add(self.listeners, a:listener)
endfunction
function! s:unregister(listener) dict
call filter(self.listeners, 'v:val isnot a:listener')
endfunction
function! s:notifyListeners(event) dict
for listener in self.listeners
call listener.update(a:event)
endfor
endfunction
let s:Subject = {
\ 'listeners': [],
\ 'new': function('s:subjectNew'),
\ 'notifyListeners': function('s:notifyListeners'),
\ 'register': function('s:register'),
\ 'unregister': function('s:unregister'),
\ }
let s:subject = s:Subject.new()
let s:listenerA = s:Listener.new('<listener A>', s:subject)
let s:listenerB = s:Listener.new('<listener B>', s:subject)
let s:listenerC = s:Listener.new('<listener C>', s:subject)
call s:subject.notifyListeners('<event foo>')
call s:subject.unregister(s:listenerA)
echo 's:subject.unregister(s:listenerA) called'
call s:subject.notifyListeners('<event bar>')
call s:subject.unregister(s:listenerB)
echo 's:subject.unregister(s:listenerB) called'
call s:subject.notifyListeners('<event baz>')
"echo PP(s:subject)
"echo PP(s:listenerA)
"echo PP(s:listenerB)
" __END__
@todashuta
Copy link
Copy Markdown
Author

結果

<listener A> received event <event foo>
<listener B> received event <event foo>
<listener C> received event <event foo>
s:subject.unregister(s:listenerA) called
<listener B> received event <event bar>
<listener C> received event <event bar>
s:subject.unregister(s:listenerB) called
<listener C> received event <event baz>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment