13.07.2015 Views

Smalltalk Best Practice Patterns Volume 1: Coding - Free

Smalltalk Best Practice Patterns Volume 1: Coding - Free

Smalltalk Best Practice Patterns Volume 1: Coding - Free

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Select/RejectHow do you execute code for part of a collection?The procedural solution is to have an enumeration block that does two things- test the element for“interesting-ness” and then conditionally perform some action on the interesting ones. Code writtenin this style looks like this:self children do: [:each | each isResponsible ifTrue: [self buyCar: each]]Code like this is fine the first time you write it, but chances are that more than likely you’ll wantthe same filter somewhere else:self children do: [:each | each isResponsible ifTrue: [self addToWill: each]]Remember the rule about saying things once and only once? These two pieces of code violate thatrule. Everything up to that second square bracket is exactly the same. We’d like to capture thatcommonality somehow.The solution is to create a collection containing only interesting elements, then operating on that.The new collection comes at a cost- it has to be allocated separately from the original collection.What is an efficient garbage collector for, if not to let you make your code more expressive. Ifallocating the intermediate collections is too expensive, you can easily fix them later.Use select: and reject: to return new collections containing only elements of interest.Enumerate the new collection. Both take a one argument Block that returns a Boolean.Select: gives you elements for which the Block returns true, reject: gives you elements forwhich the Block returns false.To capture the commonality of the above two pieces of code, we use Composed Method withselect: to create a method that returns responsible children:responsibleChildren^self children select: [:each | each isResponsible]Then we can simplify the two code fragments:self responsibleChildren do: [:each | self buyCar: each]self responsibleChildren do: [:each | self addToWill: each]You can use a special purpose Enumeration Method to avoid the cost of allocation. Use a SimpleEnumeration Parameter in the block argument. Use a Lookup Cache to optimize performance.<strong>Coding</strong> <strong>Patterns</strong> page 108 of 147 9/30/2006

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!