Smalltalk による実装

Smalltalk による実装


これは Smalltalk による実装例だ。sumim さんにソースコードを書いていただきました。ありがとうございました。

Handler クラス

"▼Handler クラス"!
Object subclass: #Handler
 instanceVariableNames: 'successor '
 classVariableNames: ''
 poolDictionaries: ''
 category: 'HMDT-ChainOfResponsibility'!

!Handler methodsFor: 'accessing'!
successor: aHandler
 "自分の後継者を決める。"
 successor := aHandler.
 ^ self! !

!Handler methodsFor: 'request dispatching'!
receive: requestString
 "リクエストを受け取り、同名のメッセージとして処理。
 自分が扱えないリクエストは後継者に託す。"
 | selector |
 selector := requestString asSymbol.
 (self respondsTo: selector)
  ifFalse: [^ successor receive: requestString]
  ifTrue: [^ self perform: selector]! !

Handler class クラス

a HelpButton、a Dialog、an Application は、preview、print、help のいずれかのリクエストに応答することができる。今、a HelpButton → a Dialog → an Application というリクエストを委譲するための連鎖があるとき、a HelpButton に preview、print、help と順次リクエストして何が起こるかを観察する。

"▼Handler class クラス(main() に相当)"!
Handler class
 instanceVariableNames: ''!

!Handler class methodsFor: 'example'!
example
 "Handler example"

 | button dialog application |
 button := HelpButton new.
 dialog := Dialog new.
 application := Application new.

 button successor: (dialog successor: application).

 World findATranscript: nil.
 #('preview' 'print' 'help') do: [ :request |
  | handler |
  Transcript cr.
  Transcript show: button printString,
    ' が ', request, ' リクエストを受け取り…、'.
  handler := button receive: request.
  Transcript show: handler printString,
    ' が処理しました。']! !

出力例:
a HelpButton が preview リクエストを受け取り…、an Application が処理しました。
a HelpButton が print リクエストを受け取り…、a Dialog が処理しました。
a HelpButton が help リクエストを受け取り…、a HelpButton が処理しました。

Application クラス

"▼Applicationクラス"!
Handler subclass: #Application
 instanceVariableNames: ''
 classVariableNames: ''
 poolDictionaries: ''
 category: 'HMDT-ChainOfResponsibility'!

!Application methodsFor: 'request handling'!
preview
 "プレビュー処理のためのメソッド…"
 ^ self! !

Dialog クラス

"▼Dialog クラス"!
Handler subclass: #Dialog
 instanceVariableNames: ''
 classVariableNames: ''
 poolDictionaries: ''
 category: 'HMDT-ChainOfResponsibility'!

!Dialog methodsFor: 'request handling'!
print
 "プリント処理のためのメソッド…"
 ^ self! !

これも、メッセージ送信をリクエストを渡すために利用している例になるね。Smalltalk は Objective-C に影響を与えたので、Objective-C での実装と比較すると、似ていることが分かるよ。