Designing Object Interactions
Object-oriented programming designs a program around a set of objects that model the entities in a problem, rather than around a single sequence of tasks.
Why Start With Things
Imagine you have been asked to write a program that keeps track of books in a small lending library. Where do you begin? Many programmers learn first to ask what the computer has to do: look up a title, record a loan, print a report. Each answer becomes a step, and the program becomes a long chain of steps in a particular order. This is a workable way to think, and it is how many programs were structured before newer styles became popular.
Object-oriented programming, usually shortened to OOP, asks a different first question. Instead of starting with the actions the computer must perform, it starts with the things that exist in the problem: the books, the borrowers, the loans. In this article we trace what that shift means, how an object is defined, and how a set of objects can cooperate to get work done.
Starting With Tasks
In a task-first design, the program is a single sequence that moves through the work from beginning to end. The designer lists the operations the computer must carry out and arranges them in order. The program's structure is therefore the structure of the work itself.
In an object-first design, the work is distributed across several objects. Each object is responsible for its own part of the information and its own behavior. The overall program then emerges from how those objects interact, rather than from one long list of steps. The diagram below compares the two shapes for the lending library. Notice that the object-first version is described as a set of things and the connections between them.
The Three Traits of an Object
Object-oriented programming designs a program around a set of objects that model the entities in a problem, rather than around a single sequence of tasks. Each object has three defining traits: it holds information, it offers behaviors, and it can interact with other objects.
The first trait is information. An object remembers facts about itself. A book object might remember its title, its author, and whether it is currently on loan. These stored facts are the object's state.
The second trait is behavior. An object knows how to do certain things with its own information. The same book might be able to mark itself as borrowed or report its own due date. Behaviors are the operations the object offers to the rest of the program.
The third trait is interaction. Objects do not sit in isolation. A member object can ask a book object to become unavailable, and a checkout process can bring the two together. When designing one object, you should consider all three traits: what it remembers, what it can do, and which other objects it must work with.
Objects That Stand for Ideas
Not every object in a program has to be a physical thing. A software object can stand for something you could touch, such as a book or a bicycle. It can also stand for something abstract, such as a loan agreement, a reservation, or a rule about how many books a member may hold at once. What matters is that the object corresponds to some entity in the problem domain, which is the area of the world the program is meant to describe.
Consider the lending library again. A Book object and a Member object stand for physical or social things a librarian deals with every day. A Reservation object and a LoanPolicy object stand for ideas: a promise to hold a book for someone, and a rule such as a maximum of five books at a time. All four are objects in the same program, and each one corresponds to an entity the library actually uses.
Starting from the entities in a problem usually produces a design that is easier to understand, because a reader can look at the program and recognize the world it describes. The quality of the design still depends on choosing good objects, so the entities you pick and the way you divide responsibilities among them matter.
Following a Borrow Event
The clearest way to see the object view at work is to follow one event through the system. Here we trace what happens when a member borrows a book. Pay attention to which object is responsible for each part of the work. Before reading on, try predicting the answer to the question below.
What do you think happens?
When a member borrows a book, which object should change the book's availability: the member, the checkout process, or the book itself?
Reveal answer
The book object changes its own status when asked
The source describes the book as able to mark itself as borrowed, and describes a member asking a book to become unavailable, with a checkout process bringing the two together. The book keeps responsibility for its own information, and other objects request the change through its behavior.
Who Is Responsible for Each Step
Read the sequence from top to bottom and ask of each arrow: which object is doing the work, and which object holds the information it needs? In step 2, the checkout process asks the book to mark itself as borrowed. The change happens inside the book, because the book is the object that holds the on-loan information. In step 3, the book reports its due date using its own behavior. The checkout process does not need to know how due dates are computed; it only needs the book to answer.
This is the sense in which information and behavior are grouped together. An object bundles its own stored facts with the operations that act on those facts. When the operations live next to the data they change, the rest of the program can ask for a result without reaching in to rearrange the object's internals.
Book State Before and After
A borrow event changes the state of the objects involved. The table below records the book's stored information before and after the event, using the generated example of a copy of Dune. Only the on-loan information changes; the title and author stay the same.
| Stored information | Before borrowing | After borrowing |
|---|---|---|
| Title | Dune | Dune |
| Author | Frank Herbert | Frank Herbert |
| On loan | No | Yes |
| Due date reported | Not applicable | Yes, reported by the book |
State of one Book object during a borrow event (generated illustration based on the source's description)
Designing a Small Lending Set
Choosing objects for a lending library
Design a simple set of objects for a small lending library that tracks books and loans, and explain how the objects cooperate.
- 1List the entities
Look at the problem domain for things that exist: books, members, and loans. Each is a candidate object because each corresponds to an entity the library deals with.
- 2Assign information
A Book remembers its title, author, and whether it is on loan. A Member remembers its name and the books it has borrowed. A Loan remembers which book, which member, and the due date.
- 3Assign behaviors
A Book can mark itself as borrowed and report its due date. A Member can request to borrow a book. A Loan can report whether it is overdue.
- 4Describe the interactions
When a member requests a book, the Member asks the Book to mark itself as borrowed, and a Loan object is created to connect the two. The Book, Member, and Loan cooperate by sending requests to one another rather than by one long list of steps.
Three objects, Book, Member, and Loan, each holding its own information, offering its own behaviors, and interacting with the others. The design follows the entities of the library rather than a single sequence of tasks.
Mistakes When Modeling Objects
Common mistake Making an object for every verb in the task list
What it looks likeCreating a LookUpTitle object, a RecordLoan object, and a PrintReport object because those were the first steps written down.
Why it failsThis carries the task-first design into an object-first program. The objects describe actions rather than entities in the problem.
Do this insteadStart from the things that exist in the problem, such as Book, Member, and Loan, and give each one the behaviors it needs.
Common mistake Giving an object only information or only behavior
What it looks likeA Book that stores its title and author but has no way to mark itself as borrowed.
Why it failsThe source defines an object by three traits. Leaving out behavior or interaction produces a passive record that cannot take part in the program's work.
Do this insteadCheck each object against the three traits: what it holds, what it offers, and which objects it works with.
Common mistake Assuming only physical things can be objects
What it looks likeIgnoring a reservation or a loan rule because it is not something you could touch.
Why it failsSoftware objects can also stand for abstract ideas in the problem domain.
Do this insteadInclude abstract entities such as a Reservation or a LoanPolicy when they play a real role in the problem.
Common mistake Letting one object change another object's stored facts directly everywhere in the program
Practice Designing Objects
A small gym tracks its members and the classes they book. Choose two or three objects for this problem. For each one, name at least one piece of information it holds, at least one behavior it offers, and one other object it interacts with. Then describe in a few sentences how a member booking a class causes those objects to cooperate.
Hints
- Start by listing the entities: what things exist in a gym?
- A booking may be a useful abstract object, even though nobody can touch it.
- Ask which object should change its own stored information when a booking is made.
Summary
- 1Object-oriented programming designs a program around objects that model the entities in a problem, rather than around a single sequence of tasks.
- 2An object has three defining traits: it holds information, it offers behaviors, and it can interact with other objects.
- 3Software objects can stand for real things such as books and members, or abstract things such as loan policies and reservations.
- 4Designing a set of objects means choosing good entities, giving each one its own responsibility, and describing how they cooperate by sending requests to one another.
At a glance
- Object-oriented programming starts from the entities in a problem, while a task-first approach starts from an ordered list of actions.
- Each object has information, behaviors, and interactions, and all three should be considered when designing it.
- Software objects can represent physical things or abstract ideas such as reservations and loan policies.
- A set of objects cooperates when each object handles its own responsibility and objects request work from one another.