[Seaside] Re: Smalltalk design advice - how to
tim at rowledge.org
Tue Dec 25 05:33:04 UTC 2007
Assume you have a collection of all the projects that interest you;
each project object (oh and be careful - there's a good chance that
there is a class called Project already in existence, so choose a
slightly more specific name) would likely instance variable for its
name, accounting code (accountants love their code numbers), manager,
purpose, company division, favourite pizza etc and, most importantly a
collection of employees assigned to it.
In your project class, implement a method to query the collection of
employees to find out if a particular employee is assigned. As it
happens, the message #detect: already exists for this purpose; it
works like this -
Given a collection containing fred, jim, bill, sheela, alice
myCollection detect:[:element| element name = 'bill']
would return the first actual employee object which responded with
true - so be careful with your tests since you may give yourself
false positives! Let us assume your test is adequately careful,
perhaps because you actually test for identity rather than just a
partial name; you will get back the appropriate employee object.
Unless it is not there - then you get an error. Whoops, better to use
#detect:ifNode: in that case. Like this
myCollection detect:[employee| employee == theEmployeeIWant] ifNone:
that way you either get the employee or nil.
So far then we can ask a particular project if a certain employee is
working on it. What about finding all the project s/he is working on?
There's a bunch of ways of iterating across collections and gathering
results - take a look at the Collection class and in particular the
'enumerating' protocol. In this case the #select: message is a
reasonable choice since it builds a collection of all the elements
that answer true when sent to the block -
companyProjects select:[:proj| proj teamIncludes:
So - we have a nice encapsulated way of asking the core question and a
nice way of building our list of projects the 'fred' works on. It's
not at all hard to extend this to find all the projects involving
several people, or a project that 'jim' isn't working on etc. There
are lots of useful enumeration methods for youto make use of.
Please, please don't give in to the temptation to give the
CompanyProject class a method that simply returns the collection of
employees and then just use some awful C programmer crap to treat
objects as mere arrays of data. Encapsulation will save you time,
effort and sanity in the long run. Any time you see code looking like
things whotsits dooberries do:[db| db subelements do:[ ......
run, screaming, away.
tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
Useful random insult:- Proof that evolution CAN go in reverse.
More information about the seaside