Decorator pattern

Lothar Schenk lothar.schenk at gmx.de
Mon Oct 6 18:30:46 UTC 2003


Phil Hudson wrote:

>> In fact, I would go so far as to make this contentious claim:
because of this lack, it is not possible to realize the Decorator design
pattern cleanly, correctly and completely in Smalltalk. That is, you can
never create a 100% transparently substitutable decorator object in
Smalltalk. (I notice the illustrative code in the GOF is in C++). I hope
I'm wrong about this, and that the real problem is just my boundless
ignorance. Anybody? <<

I don't know if I understand the Decorator pattern thoroughly enogh. Please 
have a look at the following code and tell me what you think. (It's not fully 
worked out, though. You'd probably want to use a collection for the 
decorations, so you can have more than one, and iterate over that. And the 
message forwarding in DecoratedFoo>>#doesNotUnderstand: should include 
parameters in the general case.)

"(1) Copy this into a workspace and FileIn"

Object subclass: #UndecoratedFoo
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LOS-DecoDemo'!

!UndecoratedFoo methodsFor: 'dancing' stamp: 'los 10/5/2003 18:10'!
dance

       ^ 'I don''t know how to dance.'! !

 
UndecoratedFoo subclass: #DecoratedFoo
	instanceVariableNames: 'decoration '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LOS-DecoDemo'!

!DecoratedFoo methodsFor: 'dancing' stamp: 'los 10/5/2003 18:15'!
dance

		decoration isNil ifTrue: [ ^ super dance ].

		^ 'I know how to dance. ', decoration dance.! !


!DecoratedFoo methodsFor: 'deco' stamp: 'los 10/5/2003 18:20'!
decorateWith: aDeco

		decoration := aDeco! !

!DecoratedFoo methodsFor: 'deco' stamp: 'los 10/5/2003 18:34'!
doesNotUnderstand: aMessage

	"If I don't understand a message, try if my decoration understands it"

		^ decoration perform: aMessage selector.! !



Object subclass: #DecoRock
	instanceVariableNames: 'decoration '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LOS-DecoDemo'!

!DecoRock methodsFor: 'dancing' stamp: 'los 10/5/2003 18:12'!
dance

	^ self rock! !

!DecoRock methodsFor: 'dancing' stamp: 'los 10/5/2003 18:13'!
rock

	^ 'I''m rocking.'! !

 
Object subclass: #DecoRoll
	instanceVariableNames: 'decoration '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LOS-DecoDemo'!

!DecoRoll methodsFor: 'dancing' stamp: 'los 10/5/2003 18:14'!
dance

	^ self roll! !

!DecoRoll methodsFor: 'dancing' stamp: 'los 10/5/2003 18:35'!
roll

	^ 'I''m rolling.' ! ! 
"---------------------------------"

"(2) Copy this into a workspace and execute the first four lines
with DoIt. Then examine the outcome of the rest of the lines
individually with PrintIt."

a := UndecoratedFoo new.
b := DecoratedFoo new.
c := DecoratedFoo new decorateWith: DecoRock new.
d := DecoratedFoo new decorateWith: DecoRoll new.

a dance. 
b dance. 
c dance. 
d dance. 

c rock. 
d roll. 

c roll.
d rock.

"----------------------------------"



More information about the Squeak-dev mailing list