Object Responsibility
One of the most basic concepts of object oriented design is the class. A class is one of those things that we know when we see one, but describing what it is, is a little harder. More importantly, how do we know when we are through creating one in code? What should be included in it and what should not? One definition could be when we quit typing, and that is a definition I have unfortunately seen too often in code. Designing a class correctly is more than looking at a source file and saying "This Widget doesn't have too much stuff in it, I think I'll put the code for the new Zinger in here." An object should be responsible for maintaining its own state and behaving in a way that is reasonable.
I like to think of a class as a model of something real. Suppose I had a class named Apple. What is an Apple and how do I represent it in code? Well, it probably has a name and depending on your point of view it might be "Fuji" or "Mac." Let's take the fruit and think of other things that might help describe it. Size and weight are possibilities, and so is color. We might even need some indication of whether it is ripe or a measure of its sweetness. All those things are the state of an Apple. They represent a particular instance of an Apple with variables that contain values at a particular point in time.
An object is more than just state, it also includes behaviors. Behaviors are represented by methods in our classes. What kind of behaviors can an Apple have? Watch one for a while and see what it does. If you actually did that exercise, your list of behaviors is probably pretty short. This is characteristic of a category of objects called Entities. Entities have very few behaviors. When you describe what software should do, they are some of the nouns in the description. They are typically inanimate, have very few of their own behaviors, and are acted upon by other objects. While that description is not always accurate, if you find something that fits that description you have probably found an entity. Examples of entity objects might be a Book in a library application or a DVD in video store software.
Should an Apple have a Find method that locates a particular Apple in a Basket of Apples? No, it is not the responsibility of an Apple to find other Apples. An Apple should be unaware of other Apples or even the Basket instance that is its container. So how is a particular Apple found in a Basket of Apples? Should the Basket class have a method named FindApple? No, have you ever seen a basket search for anything? I haven't. The way you model an object in code should be as close to the object in the real world as possible. It is the responsibility of a Basket to hold things, not search for them. A Person might be interested in a particular Apple. So, should a Person have a FindApple method? Probably not, but people use tools to help them do things. A type of object called a Collection knows how to manipulate multiple instances of some class. So a person would use an instance of a Collection as a tool to find a particular instance of an Apple in a collection of Apples.
To define an object we need to understand exactly what it looks like and how it behaves. We describe an object in code by the internal variables (and externally visible properties) used to store its state, other variables used to store values required by one or more of its behaviors, and only the behaviors that are required for that object. What else should go into a class? NOTHING!
While this is not meant to be the last word on object responsibility it is meant to be a guideline on how to create well-designed objects. Understanding what an object's responsibilities are helps in knowing when to stop adding things to your classes. Use common sense and good judgement and don't add unnecessary things to your classes, it just clutters up your code and makes maintaining your software harder and more time consuming.