Object-oriented programming (or OOP for short) is the dominant
programming paradigm these days, having replaced the "structured," procedural
programming techniques that were developed in the early 1970s. Java is totally
object oriented, and it is impossible to program it in the procedural style that
you may be most comfortable with. We hope this section—especially when combined
with the example code supplied in the text and on the companion web site—will
give you enough information about OOP to become productive with Java.
Let's begin with a question that, on the surface, seems to have
nothing to do with programming: How did companies like Compaq, Dell, Gateway,
and the other major personal computer manufacturers get so big, so fast? Most
people would probably say they made generally good computers and sold them at
rock-bottom prices in an era when computer demand was skyrocketing. But go
further—how were they able to manufacture so many models so fast and respond to
the changes that were happening so quickly?
Well, a big part of the answer is that these companies farmed
out a lot of the work. They bought components from reputable vendors and then
assembled them. They often didn't invest time and money in designing and
building power supplies, disk drives, motherboards, and other components. This
made it possible for the companies to produce a product and make changes quickly
for less money than if they had done the engineering themselves.
What the personal computer manufacturers were buying was
"prepackaged functionality." For example, when they bought a power supply, they
were buying something with certain properties (size, shape, and so on) and a
certain functionality (smooth power output, amount of power available, and so
on). Compaq provides a good example of how effective this operating procedure
is. When Compaq moved from engineering most of the parts in its machines to
buying many of the parts, it dramatically improved its bottom line.
OOP springs from the same idea. Your program is made of
objects, with certain properties and operations that the objects can perform.
Whether you build an object or buy it might depend on your budget or on time.
But, basically, as long as objects satisfy your specifications, you don't care
how the functionality was implemented. In OOP, you only care about what the
objects expose. So, just as computer
manufacturers don't care about the internals of a power supply as long as it
does what they want, most Java programmers don't care how an object is
implemented as long as it does what they
want.
Traditional structured programming consists of designing a set
of procedures (or algorithms) to solve a problem.
After the procedures were determined, the traditional next step was to find
appropriate ways to store the data. This is why the designer of the Pascal
language, Niklaus Wirth, called his famous book on programming Algorithms + Data Structures = Programs (Prentice Hall,
1975). Notice that in Wirth's title, algorithms come first, and data structures
come second. This mimics the way programmers worked at that time. First, you
decided how to manipulate the data; then, you decided what structure to impose
on the data to make the manipulations easier. OOP reverses the order and puts
data first, then looks at the algorithms that operate on the data.
The key to being most productive in OOP is to make each object
responsible for carrying out a set of related tasks. If an object relies on a
task that isn't its responsibility, it needs to have access to another object
whose responsibilities include that task. The first object then asks the second
object to carry out the task. This is done with a more generalized version of
the procedure call that you are familiar with in procedural programming. (Recall
that in the Java programming language these procedure calls are usually called
method calls.)
In particular, an object should never directly manipulate the
internal data of another object, nor should it expose data for other objects to
access directly. All communication should be through method calls. By encapsulating object data, you maximize reusability,
reduce data dependency, and minimize debugging time.
Of course, just as with modules in a procedural language, you
will not want an individual object to do too
much. Both design and debugging are simplified when you build small objects that
perform a few tasks, rather than building humongous objects with internal data
that are extremely complex, with hundreds of procedures to manipulate the data.
No comments:
Post a Comment