[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Objects, processes, and encapsulation
Hello Tom
Thought I'd add a footnote to your point about classic OOP weak
encapsulation. This also relates to Meyer's criticism of "active"
objects, raised by Marcel, who, like you, was sorely missed at CPA'01.
Recap
If I understood correctly, your point was that a classic object's state
is vulnerable to a reflexive invocation (call back). Your example
(#2.2.1) merged this problem with exposing the possibility of two objects
each containing the other. One of your slides (from memory) captured just
the call-back problem...
Object1 has a variable 'x' and an interface ("public methods") 'setx',
'getx',
and 'foo'. Object2 does setx(42); foo(...); y = getx. You hope y = 42
BUT foo
called a method 'bar' in Object3, which then (reflexively) called
setx(53).
I ran this past a local s/w eng enthusiast and found him quite familiar
with the problem, unfamiliar with occam, but keen on some agent model as
a solution. Interestingly, he saw agents as a formalism only, and was
quite happy they be implemented as processes. This seems to relate to
things like 'skeletons' and "higher order' programming.
Meyer and active objects
In his door-stop tome, Meyer argues that you don't want an object to do
just one thing, and illustrates the point with a printer object that can
respond to a number of different messages. It has its own agenda but will
do things for others as well. (I could think of better examples.)
He obviously hasn't considered an interface comprising channels with an
ALT behind them. We can easily build his printer. Doing your own thing,
while still providing services, ain't a problem.
Endowing occam with multiple inheritance (his other problem with active
objects) is perhaps a bit harder.
Why occam processes are still vulnerable
Unless I'm missing something, occam is only really protected by the
semantics of ALT, which allows our active object to do just one thing at
a time. So, Process2 sends a message to Process1 on channel foo, which
causes a message to be sent to Process3 on channel bar, which in turn
causes '53' to be sent back to Process1 on channel setx...which just
might be received before the request on channel getx. Whoops.
Adrian alerted us to the fact that ALT, as specified, introduces
non-determinism. You offer it messages on two distinct channels, on two
occasions, and it might trace differently each time. As implemented, it
has a kind of priority, which resolves this.
occam is a bit at odds with CSP, which either lets the process choose
(non-deterministic (internal) choice), or the environment choose
(external choice). Poor old ALT sometimes has to contend with an
environment that refuses to choose, perhaps because it is composed of
multiple interleaving processes.
With CPA, we seem to be worse off. At least the classic objects would
give the same 'y' value each time.
Better understanding the problem
Your illustration exposes another weakness in classic OOP - the patent
failure to USE encapsulation. So-called "access methods" (get<> and
set<>) defeat the aim, which is to hierarchically reduce the degree to
which program steps can interact. What's the point of containing 'x' in
some object 'y' and then directly manipulating x anyway. The whole idea
is that you act only then on 'y'. Objects then just muddy the water.
Wish I had a quid for each time I'd encountered this kind of crap.
Sadly, I've seen the same on teaching material. (We won the Battle of
Britain by forcing the best pilots to teach. The same principle used to
apply in the old Guilds. It's a shame we don't apply it to programming.)
Cause of problem and a solution
The underlying problem is that, while we've laid out our channels in
specifying our interface, we've said nothing about how they may be used.
(Much the same may be said of methods in a classic object interface.)
There's nothing preventing reflexive interaction.
The server/client design rule prohibits exactly this kind of unhealthy
behaviour. It infers how channels are used - the relation between
objects, rather than their properties as individuals. Furthermore, the
notion of 'service' allows the capture of precisely the kind of
heterogeneous behaviour Meyer describes.
It still gives protection when you allow pre-emptive service.
Nothing can guarantee good design, but this goes as far, I think, as
you can go to encourage it. It forces you to express relations, within
simple intuitive abstraction, and allows compile-time authority over
composition.
When I proposed integrating the CS design rule into a programming
language at CPA '01, the only objection was that it was too restrictive
(and perhaps too prescriptive). Maybe. Then maybe not. I think mostly
such concern comes from confusion with data flow. Only cyclic _services_
are banned. Cyclic data flow presents no problem.
Sorry this is a bit heavy. It was a good conference. My head is still
spinning.
A good strong dose of endless, boring, pointless, departmental meetings
will soon suck out all the joy again...
Ian
PS Loved the paper. Very provocative. Still find mobile
processes/channels too complex an abstraction, but agree we need
ADTs...somehow. We should meet and talk sometime.
Dr. Ian Robert East School of Computing and Mathematical Sciences
ireast@xxxxxxxxxxxxx Oxford Brookes University
(44) 1865 483635 Oxford OX3 0BP
Consultation hours for 2001/2002 Term 1
Mon 09.00..13.00