[Seaside] Re: Smalltalk design advice - how to implementgenericbi-directional pointers?

tim Rowledge 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: 
[nil]
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:  
theEmpoyeeOfInterest]

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
--
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 mailing list