Tuesday, March 25, 2008
Smalltalk Announcement Experiences
In a previous post, I described how I was interested in trying out the Announcements Framework in Dolphin Smalltalk and seeing how it changed my code.
Having ported the code to Dolphin, I set about looking at places where I had used Symbolic events and seeing how I might make use of some of the features of Announcements.
I noticed a common pattern in my GUI components (Dolphin has a very interesting GUI compositional model that bears further discussion in a separate post because it really is quite elegant) where I was looking for specific events on my model in order to update a tree widget.
(Array with: aStoryProject backlog with: aStoryProject plan)
do:
[:each |
each
when: #itemUpdated:
send: #onItemUpdated:
to: self;
when: #itemAdded:
send: #onBacklogChanged:
to: self;
when: #itemRemoved:
send: #onBacklogChanged:
to: self]
I decided to make two changes - the first being adding "," concatenation to my model (copying the idea that impressed me with AnnouncementSet), and then implementing #when:do: in the resulting ModelSet object. This made my code a little more compact:
(aStoryProject backlog , aStoryProject plan)
when: StoryCardUpdatedAnnouncement
do: [:ann | ann treeModelUpdate: self model: treeModel];
when: StoryCardAddedAnnouncement, StoryCardRemovedAnnouncement
do: [:ann | ann recalculateFilterFor: self ].
I also created a hierarchy of StoryCard announcements, which I could then add methods to (in this case #treeModelUpdate:model: and #recalculateFilterFor:) and then call in my announcement Blocks. This change reduced a lot of clutter in my code, as these methods replaced the #onXXXX: methods that were sitting in several GUI components (some confusingly inherited, and some blatantly copy and pasted). The use of the "," operator for the Added and Removed announcements also feels a little more expressive as well.
As I worked through more examples, I also noticed that if my models start announcing changes, then I need a way to conveniently tie those announcements to GUI objects in a Dolphin manner:
model: anIteration
| velocityProposer |
super model: anIteration.
teamSizePresenter model: (anIteration aspectValue: #teamSize).
velocityProposer := VelocityProposer for: anIteration.
suggestedVelocityPresenter model:
(velocityProposer aspectValue: #suggestedVelocityRangeString).
suggestedVelocityPresenter model aspectAnnounces: VelocityChanged.
The above code shows how a normal number presenter can be bound to a #teamSize aspect of anIteration model. However it's also useful to bind to other types of aspects like #suggestedVelocityRangeString which can change dynamically by way of an Announcement (in this case VelocityChanged). This is analogous to the Dolphin #aspectTriggers: method, but instead works for announcements.
I'm still feeling my way through converting to using Announcements, however so far I have been quite pleased with the results. They haven't been ground breaking changes, but they certainly feel tidier
Labels: Dolphin, Programming, Smalltalk
Subscribe to Posts [Atom]
