While musing on asynchronous events and distributed control, I had a look at
the subsumption architecture (SA) of Rodney Brooks, for robots with no
centralized control or representation of the world (very radical at the time
he first introduced it). I wondered if OO is a subsumption architecture or
not, or if his ideas could be adapted to OO. In essence, SA uses layering.
Each layer is a bunch of finite state machines (FSM, which are like objects)
that receive 'messages' or 'events' and can act on them by issuing output
signals (usually to an actuator device). For example, the first layer might
implement the behaviour 'breathing' or 'avoiding obstacles'. Higher layers
can wrest control of the lower layers, and so turn 'breathing' into
'singing' or 'talking'. You get the idea. The important bit is that each
layer uses the one below it, and that if anything in a higher layer breaks
(or the higher layer is simply not active) the lower layer automatically
gains control. This last bit, and the independence of the components, is
where the robustness comes from.
My immediate thought was that OO and Software engineering do this already.
For example, the lower layer can be thought of as the basic method in an
ancestor, and the higher layer is the same method, overidden to provide new
behaviour in the descendant. At a higher level, software is often layered,
so that the drawing primitives are on the bottom layer, and windowing
functions on a higher level.
However, subsumption is subtley different. Time is important. The problem
with method overriding is that the behaviour is changed for all time, with
no reverting to the original method. For one layer to gain control over a
lower layer, it has to actively suppress the lower layer. It only has
control while it is supressing. It is like having a method that says,
whenever the screen is orange, print 'layer 2'. As soon as the screen is not
orange, the method does nothing, but the ancestor method magically gets
invoked to print 'layer 1'. It is more like a wrapper, where the outer
object tests to see if the screen is orange. If it is, it invokes its
method, otherwise it delegates to the wrappee. Or like the state pattern,
where the state object gets swapped whenever the screen changes colour. But
these concepts are more brittle - if the wrapper dies or the state-swapper
dies, the basic behaviour dies with it. In the subsumption architecture, the
lower layer is automatically reinvoked. It seems as though you will need to
run the high and low layer objects asynchronously and in parallel to get the
robustness of the SA. Many threads all simultaneously fighting for control
seems to get the effect.
I was going to add some more, but it's time to go home.
Any thoughts on using the subsumption architecture to make OO programs more
robust, and how it would be done?
Peter