What we want to do here is to analyze our problem and identify the data that the program must deal with, and the things it must do. These are referred to by the text as the 'knowing responsibilities' and the 'doing responsibilities' respectively. Since our software will be a collection of classes (remember, everything in Java is in a class!), our job in the design stage is to distribute the knowing and doing responsibilities amongst the classes.
So our first principle of design is:
1. Identify all 'knowing' and 'doing responsibilities'. Describe them in English. Assign these responsibilities to classes
But how do we know what classes we'll have? What we'll try to do is to mirror the 'natural structure' of the problem. In our case we have the following structure: courses have sections, sections have students, students have student information. This suggests that we should have a course class so that we can make course objects, a section class so that we can make section objects, a student class so that we can make student objects. A course object will contain some references to section objects ( and therefore a course will 'know' about its sections), a section object will contain some references to student objects (and therefore a section will 'know' about its students) and a student object will contain student data (so that a student will know her data).
Our second principle of design is
2. Mirror the 'natural structure' of the problem.
This will help us in thinking about how the program works since we'll be able to draw analogies easily from the real situation.