[Q] Fiddling with system innards, was [Q] Newbie - Multiple
Return Values
John W. Sarkela
sarkela at sbcglobal.net
Thu May 1 18:00:28 UTC 2003
Hello Ingo,
Welcome to the world of Smalltalk. I ask you to prepare yourself to
turn all of your ideas about the "proper order" of things inside out.
Much of the wisdom of your experience will apply in this world, much
will not. Your task is to draw that distinction effectively.
The first observation is that the world of Smalltalk consists of two
basic elements,
1. The imperative, the message send
2. The structure, the class
There are no other elements inherent in the world of Smalltalk, not
even control structures.
So, don't be afraid to create classes to model the structure of intent.
Classes are inexpensive and the *only* way to express structure in the
environment. So use classes to define the structure and order of your
system. There is no other option in Smalltalk.
With regard to Exceptions, it is quite appropriate to use exceptions as
a means of signaling failure. As a designer, I wish to make the network
architecture transparent with respect to the logical architecture of
the system as a whole.
Thus
1. Assume all sends succeed. If a call returns it was successful. If
not I am certainly in a state that I would hope to be truly exceptional.
2. At network boundaries wrap a handler that handles out of band
occurrences. This would include not only link problems, but also
asynchronous signals from the other endpoint. I have in the past put
these behaviors in the proxies that abstract the network link from the
object model.
One of my rules of thumb is that if my logical architecture (domain
model) has knowledge of and dependency upon my technical architecture
(platforms and channels) then I am not done designing.
On Thursday, May 1, 2003, at 09:53 AM, Ingo Hohmann wrote:
> Hi Cees,
>
> Cees de Groot wrote:
> <..>
>> Really, encapsulating the result in a class is much nicer, especially
>> because you can then start converting 'tell' methods into 'ask'
>> methods
>> (don't "give me foo" but "please do bar with whatever you represent").
>> There's about zero overhead (probably exactly zero - whether you
>> construct an Array instance with two or three members or a FooResult
>> instance with two or three instance vars does not matter).
> <..>
>
> I'm quite willing to sacrifice some performance for clarity (otherwise
> I'd be using assembler, or even -uuuugh- C), but
If instances of your result class are sufficiently explicit, not only
will code clarity increase, but most likely the code will be more
efficient. This is because a FooResult never needs to perform
conditional tests at runtime to know what kind of thing it is.
A consequence of pushing discrimination to design time (ie the design
of the structure of classes) is that at runtime there is no need for
conditional testing to determine course of action. Paradoxically, his
very often result in code speed ups.
As a side note, the following artifacts are all signs of missing
classes,
Arrays used as temporary structures.
Methods with lots of arguments
Lots of conditional tests
Inquiry as to the class of a receiver
> where I come from fiddling with the system innards is supposed to be a
> 'black art'.
>
Usually motivated by runtime environments that are not robust and that
are inflexible, not because it is inherently black or to be avoided.
> Actually, my problem is that, everything I do is in the image to stay
> - that's quite a difference to writing a script that changes whatever
> it wants to in the system, when it does not interfere in any way with
> other scripts/programs.
>
> _That's_ why I am reluctant to create new classes.
If your classes reflect a truly distinct intent and are manifest in new
vocabulary, there will be no negative interaction. My experience has
demonstrated time and again it is more likely that you will experience
the surprise of your new definitions working in meaningful ways you had
not considered.
>
> On a related note, assume I would like to do something with
> strings/any standard class, that the current implementation does not
> allow. What is the way to go then?
>
> Should I extend the String class in the system?
> Create a subclass of String that understands my additional messages?
> Create a StringHelper which understands #myMessage: aString?
>
> The latter seems to be the cleanest to me, what do you think?
If you have distinguished a new vocabulary that applies to Strings,
then by all means extend the class String. Anything else is a dilution
of intent. In a more rigid system, one would be taught a pattern of
encapsulation (such as StringHelper) or subclassing in order to
overcome the limitations of the runtime.
In summary,
Model distinctions with classes.
If something needs to be done, send a message.
When sending a message, consider
to whom (what classes of objects) should the message be sent?
is the intent of the message explicit in the method selector?
If a method has conditional behavior, ask yourself
does this test reflect a distinction that is not modeled by class
structure?
If a method has lots of arguments or your are returning arrays, ask
yourself
are these arguments (or array) suggesting a new class of object?
>
>
> Kind regards,
>
> Ingo
>
The most important lesson of all is to dare to have fun. Experiment and
learn, these are the driving principles hiding in Smalltalk.
Cheers,
:-}> John
More information about the Squeak-dev
mailing list
|