Chapter 1 of API Design
The Object
Guideline 1. Design objects for people, not for computers
by Bill Venners
Part 3 of 21
Managing
Change
Besides complexity, another fundamental challenge
of software development is change. If a software project doesn't
fail initially, the resulting code base tends to have a long life.
With each new release comes new requirements. Existing code is tweaked
and enhanced to fix bugs and add functionality. Objects, in addition
to helping programmers manage complexity, help programmers manage
change.
One ideal of object-oriented programming is
a strong separation of interface and implementation. The primary
enemy of change in a software system is coupling, the interdependencies
between various system parts. The aim of separating interface and
implementation is to help programmers minimize coupling in their systems.
At a keynote address I saw Bill Joy give at the Software Developer
conference in Washington, D.C., Joy described coupling by saying,
"You slap your hand on this table in Washington and a building
falls down in San Francisco." In other words, you make a small,
seemingly innocuous change in one part of your system, and you inadvertently
cause a disaster in a remote and unrelated part of your system.
In an object-oriented system, object interfaces are the point of
coupling between different system parts. Because interfaces are
the only point of coupling between the parts, you can make many
kinds of changes to implementations without breaking the expectations
of client code. When you slap the implementation of a Table
object
in Washington, all the Building
objects in San Francisco continue
to stand tall.
Objects also help programmers deal with change
by being replaceable modules. Polymorphism and dynamic binding enable
you to unplug one implementation of an object interface and plug
in a different implementation of that interface. This makes it easy
to change a system by defining a new class that extends an existing
class or implements an existing interface
. You can
instantiate the new class and pass the resulting object to existing
code that knows only of the supertype.
Lastly, objects help programmers manage change
because object contracts can be very abstract. An object's contract, the human
language description of what the object promises to do when you
invoke its instance methods, is usually expressed in terms of behavior.
Instance data is kept private. The structure of instance data and
code of instance methods do not appear as part of the object's contract.
Contracts expressed in terms of behavior can be very abstract, simply because
you can be vague when you describe behavior without specifying particular
data structures or code algorithms. The higher the level of abstraction
in a contract, the more options programmers have when changing an
implementation, or plugging in a new implementation, of a class.