Object-oriented decomposition -- why and why not

Feb 24, 2009 | George Fairbanks

My friend Nels Beckman is writing on
how to do functional programming in
. He asked me why
I thought people build systems that follow an OO decomposition. Since
my boss has been relentless about getting the book done, I have not
posted a blog recently, so here’s my note to Nels.

When you decompose systems, at some point you have a chunk (module,
component, …) that you want to structure internally. How do you do
that? One of the strategies is to mirror domain concepts. This
actually works fine in most IT cases (and probably most others too,
once you get used to it). There is an argument that the domain
concepts (nouns) change very slowly, while the their behaviors seem to
always be evolving (verbs). So if you align your structure with the
nouns you get less churn induced by the domain changing. This OO
strategy implicitly promotes modifiability.

Your suggestion to use a functional programming style is similar to
the “orthogonal abstraction” I describe in the book — in the
functional case it is usually some math formalism, hence the desire to
work with tuples instead of a domain-specific concept. I can see two
big advantages to the orthogonal abstraction. First, it could be much
faster (or some other quality attribute). In fact it would be
surprising if the OO strategy was the fastest — why would the way
things are “in real life” naturally align with performance? And
second, it could be that there is a domain that has already been well
studied (e.g. compilers, databases, static analysis) that has its own
set of (stable) abstractions. Experts have decided that these are the
essential concepts and they work well.

A day in the life of an IT programmer is a frustrating exercise in
what is not known. It is not about engineering a great solution to
a known problem. Perhaps this is an under-appreciated fact in
academics, and it would explain many prejudices. You’re just some guy
trying to make the system do what the marketing / sales / customers
want it to do. You never understand the domain (banking, inventory,
insurance, etc.) as well as the experts. You are always building an
approximation of what they’d really like to have. They always wish it
was already built and you always build it too slowly. What you built
yesterday doesn’t really support what they want tomorrow. I think
systems/OS guys feel less like this — they have less churn in their
domain and they spend more time working on optimizing the internal
implementation of a module/component.

There’s a story about building a system to track boats on a lake. The
first design is an OO one, with classes representing boats, trips, and
fares; it can tell you what the cash register should hold at the end
of the day. The second design is minimal: just keep two counters that
sum the departure and return times of each boat. At the end of the
day, subtract the departure counter from the return counter to get
total minutes and multiply by rate. Ta da. But if you ask for any
change to the OO system (say discount fares after 5pm) it’s easy to
add because the change is relative to the domain, which is already
encoded in the design, while the other solution has pruned the problem
to its core, so you’d have to start over to change anything. I’m not
saying this story is accurate — it’s a fable so it’s exaggerated —
but the nugget of truth is there, including the extreme simplicity of
non-OO solutions. (If anyone knows the origin if this fable please
let me know).


George Fairbanks is a software developer, designer, and architect living in New York city


+1-303-834-7760 (Recruiters: Please do not call)
Twitter: @GHFairbanks