Command Dispatch Pattern
31Jan2009
This is really elegant, although it's not very well-suited for statically typed languages. This is part of a Smalltalk scanner:
Scanner initialize [ super initialize. (charTable := Array new: 256) atAllPut: #xIllegal; atAll: '0123456789' asByteArray put: #xDigit; atAll: 'abcdefghijklmnopqrstuvwxyz' asByteArray put: #xLetter; atAll: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' asByteArray put: #xLetter; atAll: '_' asByteArray put: #xLetter; atAll: '~!@%&*=\\?/><,|^' asByteArray put: #xLetter; atAll: '+-' asByteArray put: #xSign; ... at: $' asciiValue put: #xString; at: $" asciiValue put: #xComment. ] Scanner scan [ ... c notNil ifTrue: [self perform: (charTable at: c value)]. ... ] Scanner xSign [ ^context peek isDigit ifTrue: [self xDigit] ifFalse: [self xBinary] ] ...etc
Source: The FONC repository, Scanner.st by Ian Piumarta. License: 'AS IS'.
How it works:
- Character 'a' is passed.
- Object looks up which method to use in that case.
- The object retrieved the result of that lookup.
- The object calls the method on itself.
The advantage? You can avoid these ridiculously large switch-like
constructs. Also note the concise way in which the table is
constructed. svn praise
!
A description of the same technique applied in Python can be found in this python pattern collection.