The traditional way of thinking about objects, encapsulation, and inheritance is very limiting. In this chapter from Design Patterns Explained, the authors describe a new way of seeing object-oriented design, which comes from the perspective that design patterns create.

Overview

In previous chapters, I discussed three fundamental concepts of
object-oriented design: objects, encapsulation, and abstract classes. How a
designer views these concepts is important. The traditional ways are simply too
limiting. In this chapter I step back and reflect on topics discussed earlier in
the book. My intent is to describe a new way of seeing object-oriented design,
which comes from the perspective that design patterns create.

In this chapter,

I compare and contrast the traditional way of looking at objects—as
a bundle of data and methods—with the new way—as things with
responsibilities.

I compare and contrast the traditional way of looking at
encapsulation—as hiding data—with the new way—as the ability to
hide anything. Especially important is to see that encapsulation can be used to
contain variation in behavior.

I compare and contrast the traditional way of using inheritance—for
specialization and reuse—with the new way—as a method of classifying
objects.

The new viewpoints allow for containing variation of behaviors in
objects.

I show how the conceptual, specification, and implementation
perspectives relate to an abstract class and its derived classes.

Acknowledgment

Perhaps this new perspective is not all that original. I believe that this
perspective is one that many developers of the design patterns held when they
developed what ended up being called a pattern. Certainly, it is a perspective
that is consistent with the writings of Christopher Alexander, Jim Coplien, and
the Gang of Four.

While it may not be original, it has also not been expressed in quite the way
I do in this chapter and in this book. I have had to distill this way of looking
at patterns from the way design patterns behave and how they have been described
by others.

When I call it a new perspective, what I mean is that it is most likely a new
way for most developers to view object orientation. It was certainly new to me
when I was learning design patterns for the first time.

Objects: the Traditional View and the New View

The traditional view: data with methods

The traditional view of objects is that they are data with methods. One of my
teachers called them "smart data." It is just a step up from a
database. This view comes from looking at objects from an implementation
perspective.

The new view: things with responsibilities

While this definition is accurate, as explained in Chapter 1, "The
Object-Oriented Paradigm," it is based on the implementation perspective. A
more useful definition is one based on the conceptual perspective—an object
is an entity that has responsibilities. These responsibilities give the object
its behavior. Sometimes, I also think of an object as an entity that has
specific behavior.

This is a better definition because it helps to focus on what the objects are
supposed to do, not simply on how to implement them. This enables me to
build the software in two steps:

Make a preliminary design without worrying about all of the details
involved.

Implement the design achieved.

Ultimately, this perspective allows for better object selection and
definition (in a sense, the main point of design anyway). Object definition is
more flexible; by focusing on what an object does, inheritance allows us to use
different, specific behaviors when needed. A focus on implementation may achieve
this, but flexibility typically comes at a higher price.

It is easier to think in terms of responsibilities because that helps to
define the object's public interface. If an object has a responsibility,
there must be some way to ask it to perform its responsibility. However, it does
not imply anything about what is inside the object. The information for
which the object is responsible may not even be inside the object itself.

For example, suppose I have a Shape object and its responsibilities
are

To know where it is located

To be able to draw itself on a display

To be able to remove itself from a display

These responsibilities imply that a particular set of method calls must
exist:

getLocation( ... )

drawShape( ... )

unDrawShape( ... )

There is no implication about what is inside of Shape. I only care
that Shape is responsible for its own behaviors. It may have attributes
inside it or it may have methods that calculate or even refer to other objects.
Thus, Shape might contain attributes about its location or it might
refer to another database object to get its location. This gives you the
flexibility you need to meet your modeling objectives.

Interestingly, you will find that focusing on motivation rather than on
implementation is a recurring theme in design patterns.

Look at objects this way. Make it your basic viewpoint for objects. If you
do, you will have superior designs.