This represents the beginning point of a series of papers by myself and others that will use Software Patterns to explain the elementary topics of object-oriented computer programming. As such, it is is the main focus of the first course in Computer Science in many Universities. Most of the examples in these papers will use Java to illustrate concepts, though it is not a tutorial in Java. The focus will be on problem solving in the object-oriented context.
Here is a nice little story that can help set the stage for understanding objects.
You have been given a problem to solve. How do you begin thinking about developing a solution?
Object-oriented programs are collections of interacting objects. The objects exhibit behavior and the behavior is encapsulated within the objects so that each object knows what it it capable of.
Therefore, begin by finding objects in the problem that might be represented directly in the program. Make a list of the major "players" in the problem statement and try to describe what they must do in terms of services they provide for others. For each object you list decide what its major responsibilities are and write these down. Also note whether there are many objects of this same kind or only one. Three by five cards are a good tool to use to write down objects and their responsibilities. One object per card with its responsibilities written on the card as well.
As a sanity check, make sure that every object has some responsibility and that all the requirements of your problem have been covered in the set of responsibilities. Each object needs to be able to answer the questions: "What can I do?", "What do I know?", and "Who can I talk to?" This is because most responsibilities are either actions to be performed or information to be remembered and given to clients. Also, objects need to be able to communicate with other objects as helpers (servers, actually).
How much responsibility should an object have?
If an object has lots of responsibilities it will likely be very complex. This will make it hard to understand and difficult to modify. Remember that programs in the real world get modified constantly. We must prepare for this.
Therefore, don't give too much responsibility to any one object unless it can use other objects to help it with its tasks. Each object should have one major responsibility. If an object has more than one responsibility, they must be closely related.
If the objects provide services with their responsibilities, how do I model the client-server relationships?
Clients are also objects. Their responsibility may be to communicate with the external user or with other (server) objects to get a complex task done. Each client needs to know which objects provide it services.
Therefore, when you write down a client object, list the server objects that it must communicate with. Connect clients to servers. You may want to do this with pictures as well, but each object needs a listing of its servers. In the picture, an arrow from a client to each of its servers is standard documentation practice.
How is the problem statement related to the object decomposition?
There are several patterns that can help answer this.
You are engaged in finding objects. What are good candidate objects?
A program is a technical description of a solution, but the solution must be closely related to the problem. In natural language, nouns are words that name and describe things. Objects are (electronic) things.
Therefore, a good place to find objects is to look for the nouns in the problem description. To find the responsibilities of these objects look at how they behave in the world in which the problem itself lives. Nouns won't always do a good job of designing the solution, but they are a good place to start. The objects we initially list are called candidate objects until we decide they really belong in the program.
What behavior should I assign to these new candidate objects?
A program can be thought of as a model of some real world situation or thing. An accounting program models the business practice of the firm that uses it. A computer game models some activity that humans do (thinking, fighting,...)
Therefore, a good way to assign responsibilities to candidate objects is to give them the same responsibilities and behaviors that they would have in the real world if they were real. In other words, model the real world. As you do this, remember that an object can provide information to other objects. It can also act on behalf of another object. Therefore, think client-server as you assign responsibilities.
How do I know if I have the right objects?
This is partly a matter of experience, but there are some guidelines as indicated in the following patterns.
How do I know if my candidate objects will provide a solution to the problem?
Before you can begin writing down actual Java programs, you need to have a pretty good idea that the objects you have will solve your problem. You have already listed candidate objects and their responsibilities (services). You also know if you need one object of a given kind or several. Finally, you know (or at least think you know) which objects will need to ask which other objects for services. With this information you can do a simple simulation of the problem you want to solve.
Therefore, with enough people so that each person can take the role of one of the objects, role play a solution to the problem. One person may need to play the role of a user who talks to (communicates with) some object in the "system" that will handle user input. That object requests information and actions from other objects (servers) who in turn ask other objects, which eventually create and return the information needed.
When you roll play, try to look for awkward communication patterns and try to eliminate them, either by changing the object structure or by reassigning responsibilities. You would like the objects to be simple and to communicate in simple ways, passing as little information among themselves as possible.
As you roll play, make sure that you have a solution to the problem at hand and that you have sufficient responsibilities to cover all of the requirements.
As you roll play, make a note of what information needs to be remembered by each object as you proceed and how long that information needs to be remembered.
What should I look for in the communication paths in my set of objects?
You want simple communication paths in which the information doesn't have to flow through intermediaries who only pass it on. Each object that "sees" any information should need to see it, either because it creates it, modifies it, aggregates it with other information, or uses it.
Therefore, avoid indirect communication.
What are the consequences of a set of objects where many of the objects communicate directly with one particular object?
This might be necessary or not. However, "star" designs with one object controlling many others is often a poor design and the central object often has too many responsibilities and often has complex structure. We want to avoid this.
Therefore, avoid communication bottlenecks.
Pull your own weight
Iterate the Design
Last updated: April 30, 2000 10:36 AM