I've consistently avoided OO. I've tried to avoid problems that are
complicated enough for OO to be valuable.
But various recent clf posts have given me the idea that these days,
avoiding OO is like avoiding structured programming. You can maintain
software adequately without formal structuring, but there's no point
trying to get anybody to believe you.
So I did a quick lit search, and came to some obvious conclusions that
don't seem to match the conventional wisdom. It looks like OO aids
programming by organizing code. When you act on an object you don't have
to remember what data type you're accessing. The object tells you, or
better yet it makes sure it links up to the right datatype without
telling you what happened. And if you try to give it the wrong datatype
then almost certainly you have made a mistake, because if another OO
routine has produced the wrong type then it wasn't producing something
intended for this object to interact with. If the two were designed to
fit together they'd actually match up. So instead of doing a conversion,
it's better for the system to tell you about your probable logic error.
This makes it easier, because you don't have to think as much about the
details of how things fit together. But it comes at a cost. You have to
think out all the possible ways things can fit together, ahead of time.
So you get complexity piled on complexity. Still, if the particular
objects are designed superbly then somebody who doesn't know what he's
doing can "maintain" them -- fit them together in new ways -- and avoid
catastrophe. Because whenever he tries to do something that won't work,
it refuses to do it instead of letting him add bugs.
But as the design patterns show, the whole thing has been bogged down in
complexity. It attempts to provide default interactions so you don't
have to think about the details. But then inevitably you do need
nondefault interactions and you have to think about the details very
carefully. So we have design patterns like:
Adapter Convert the interface of a class into another interface clients
expect. Adapter lets classes work together that couldn't otherwise
because of incompatible interfaces.
Bridge Decouple an abstraction from its implementation so that the two
can vary independently.
Composite Compose objects into tree structures to represent
part-whole hierarchies. Composite lets clients treat individual objects
and compositions of objects uniformly.
Decorator Attach additional responsibilities to an object
dynamically. Decorators provide a flexible alternative to subclassing
for extending functionality.
Facade Provide a unified interface to a set of interfaces in a
subsystem. Facade defines a higher-level interface that makes the
subsystem easier to use.
*You need methods to work around the benefits your objects give you.*
Chain of responsibility Avoid coupling the sender of a request to its
receiver by giving more than one object a chance to handle the request.
Chain the receiving objects and pass the request along the chain until
an object handles it.
Iterator Provide a way to access the elements of an aggregate
object sequentially without exposing its underlying representation.
Mediator Define an object that encapsulates how a set of objects
interact. Mediator promotes loose coupling by keeping objects from
referring to each other explicitly, and it lets you vary their
interaction independently.
Observer Define a one-to-many dependency between objects so that
when one object changes state, all its dependents are notified and
updated automatically.
Visitor Represent an operation to be performed on the elements of an
object structure. Visitor lets you define a new operation without
changing the classes of the elements on which it operates.
*You need methods to flexibly handle extreme complexity.*
Lazy initialization Tactic of delaying the creation of an object,
the calculation of a value, or some other expensive process until the
first time it is needed.
Object pool Avoid expensive acquisition and release of resources by
recycling objects that are no longer in use.
*You need methods to reduce the expense of all this OO complexity.*
OO is a mature technology that's mostly failed. The promise was that it
would work. The reality is that it can be made to work with a lot of
inspired hard work, but by default it doesn't particularly get results.
It's an improvement over random activity. Using some specific object
modules is an improvement over re-inventing everything from scratch
every time.
We're probably ripe for something new. Something that claims to fulfill
the promises that OO made and failed at. People won't agree to go back
to the bad old days before they had OO, when there was no way to get a
good result except hard work and inspired improvisation. They'll want
something new that looks even better.
I'd like to predict what the new thing will be like. It has to explain
why OO has failed. It must promise to succeed at those things and more.
Do you have links to the clearest explanations about OO's promises? What
was it exactly that project managers needed and didn't have, that they
hoped OO would give them?


|