design patterns in Self

Huebner Michael.Huebner at PrakInf.TU-Ilmenau.DE
Wed Aug 30 12:43:01 UTC 1995


A time ago I played with Self and was impressed by its way of delegation.
Now I'm reading the book "Design Patterns" from Erich Gamma, Richard Helm,
Ralph Johnson and John Vlissides. They describe wellknown structures in
oo programming, like Adapter, Abstract Factory, Wrapper etc. .
When I look at the examples in C++ or Smalltalk I think that the often used
mechanism of forewarding a message to a component can be done easier with
delegation. 
So my question: Has anybody thought about Design Patterns in Self?
Maybe he found in object-based languages different structures of collaborating 
objects that are often used than those in object-oriented languages.
How are the patterns from the book of "the gang of 4" implemented in Self.
Are they easier to implement or are there other problems.

When I thought about the Wrapper (alias Decorator) pattern, I found that 
this pattern would look in Self similiar to the solution in Smalltalk.

As you might know a wrapper is an object that acts as its component but 
changes (enriches) the behavior of its component by redefining the original
methods of its component. In most cases the original method is called inside
this new method implementation. 

All method calls on methods that haven't been changed are simply forwarded 
to the component.
In oo languages this is done by explicit forwarding: component.selector
in ob languages this could be done by delegation: component in a parent slot.
  
It is possible to chain wrappers because the user of a wrapper can't tell 
the wrapper from its component.

My thoughts led to the conlcusion that the delegation solution isn't possible
because of the possibility of unwished inferences of private methods of the
component with private methods of the wrapper.  

Example1:	works fine

+-- Wrapper ----+				+-- Component --+
| component* ...............................>	| m = ( ..i.. ) |
| 		|				| i = ( A2 )	|	{ A2 = right for Component }
+---------------+				+---------------+	{ A2 = false for Wrapper }

Example2:	unwished inference 

+-- Wrapper ----+				+-- Component --+
| component* ...............................>	| m = ( ..i.. ) |
| i = ( A1 )	|				| i = ( A2 )	|	{ A1 = right for Wrapper }
+---------------+				+---------------+	{ A1 = false for Component }

So there is no save use of delegation for the wrapper pattern.
A second reason against delegation in this case is that every redefined method
must be inside (not be delegated) the wrapperObject to avoid ambiguitious
method resolution which leads to big clumsy objects

Maybe other patterns gain more from the Self specifics. I would like to hear
about it.

Michael




More information about the Self-interest mailing list