|
Re: Name spaces in Dolphin...
panu wrote:
>
> cstb wrote:
> >
> > (3) In your code, always refer to
> > transformer via the local method
> >
> > (self transformer) selectorWhatever
> >
>
> I think I see your point, but I'm not quite
> convinced that the added encapsulation is
> worth the added complexity (then again I may
> not quite get what your example correctly) .
Just noting that, whereas you put the
responsibility for answering an actual receiver
in an instance method, I suggest moving it
to the class side (whenever it will answer aClass).
So the trace is
(self transformer) selector
--> (self class transformer) selector
--> ActualReceiver selector
The second line of the trace is
the 'added complexity', but if you
do this all the time, its very easy
to follow. In fact, it gets exceptionally
easy, as we'll see below.
> There's some added complexity in the above.
> First of all every reference to a global/class
> now gets longer (if I get you correctly, right?).
If by longer you mean
takes one more indirection hop
then yes, it is longer. But I wouldn't
agree that this increases the 'complexity',
either formally or informally.
You can obviously ignore the 'cost' of the extra
indirection, as one doesn't refer to another class
very often, so the extra time is minuscule. In the
rare cases that this isn't true, either
a) you should think about refactoring,
as someOfThisCode wants to be
in that other class
or
b) you've got an otherwise working solution, but
which fails to meet some performance requirement
AND
profiling the code tells you that removing
this particular indirection will have a
significant effect toward speeding it up.
>
> Whereas the rule "Instead of accessing a class
> directly, always call a method that returns it"
> seems to be *easy to grasp*, and *easy to remember*.
>
My version of your rule, then, is two parts:
1) "Instead of accessing a class directly,
always ask yourself which class to use.
(self whichClassToUse) whateverTheSelectorIs...
2) "When you are asked which class to use,
always query your own class side for the answer.
self>>whichClassToUse
^self class whichClassToUse
self class>>whichClassToUse
^TheActualClass
> > ...
> > Advantages: Encapsulates further, as client
> > doesn't need to know the class
> > side methods,
Meaning - [and not that you do this, just that one shouldn't]
Don't directly refer to your own
class side methods using CapitalizedSelectors,
(as is sometimes suggested) - instead,
always refer to a forwarding method
that is defined on the instance side.
Result:
1) Scanning some code, you see a reference:
self thingAmaJig doSomething
You don't know about thingAmaJig,
so you look for it (in the all categories list)
- and find it in the category 'accessing class'.
You now know (without looking at it)
that it is either answering a constant,
or a collaborating class, and decide you
can safely ignore that detail for now.
You return to scanning the original
code.
2) You want to modify a class,
changing a collaborator.
You go to the class side, and select the
category 'collaborators'.
You look at all the methods, and one of them
just answers ThingAmaJig. That's the guy
you want to swap out. The name of the method
answering ThingAmaJig is #thatThingYouUse,
so you browse local senders of #thatThingYouUse,
and you get a list of every place this class
is using ThingAmaJig, i.e. by looking at just
these spots in the code you'll know the actual
protocol being used with ThingAmaJig.
So now you know -
you can indeed replace ThingAmaJig with
NewFangledCoolness because (having written it,
you happen to recognize) the latter also defines
all the methods that are actually being
used on ThingAmaJig -- used *by this class*.
You do not care about any other methods
ThingAmaJig might define, because only the
ones listed in the browser window right
now are used *here*, in the class you
want to change. The other 6,432 methods
defined on ThingAmaJig (a god class, obviously)
are not used here at all, so you don't have
to bother defining them on NewFangledCoolness.
You don't even have to read them.
Lucky you. Nice convention.
> ...
>
> Sending something to self is the closest
> thing to "encapsulation" I can think of.
That's right.
There's only one thing closer, which is
- don't send to anyone -
i.e. reference an instVar directly.
But I wouldn't advise doing this *unless*
you happen to have a reasonable refactoring
tool on hand, one that will let you change
your mind and switch all the getters to
directRefs, and back to getters again,
at will.
Which of course you do, so go ahead.
Lucky you.
(do stick to the convention in
the <Class> case though...
)
>
> Cheers
> -Panu Viljamaa
Cheers,
-cstb
|