Organization of a Large Object-Oriented Project
Clarify the purpose of the project and set short-term goals
- Make a list of features that the client wants
- Think about each feature. Who is it for, and why is it important
- Clarify each feature so you make sure you know its purpose
- Prioritize your features list
- Use the features list for planning and building frequent, tangible working
results
Create an interface and see if it meets the needs of the user
- For each part of the project see what the user wants and when it is needed.
- What input and output will best serve the user.
- Sometimes in discussing the interface you get a better idea of what the
user actually wants and needs. Also get a better idea of what is easiest for the
user.
- Once you have discussed the interface with drawings, do a mockup of the
interface and see if the user is still happy.
- Your mockup can simply ask for input (if required) and pass back faked data
to show how the program will work.
Determine the class structure of the Application Classes
When you have a firm idea of what the user wants, you can design classes based
on these requests.
How do you decide on the classes needed?
- Locate nouns in your description of the problem. Most of these will
be classes.
- Are there controls in the interface that display lists of items? If so, you
will use container classes.
- These are likely to be smart wrappers around STL containers. Remember to use
"smart components", i.e. first-class objects as the elements of containers.
How do you determine the operations on each class?
- Identify use cases (scenarios) of how the application is going to be used.
- Locate verbs in this description. Most of these will be operations
(functions, methods, behaviors).
- Are there a series of related operations? If so, you may use a hierarchy of
classes, one for each operation, to represent these operations.
Software Engineering Themes: The Fundamental Guidelines of Class Design
- Separate interface (public) and implementation (private).
- Create and use first-class types (smart components).
- Code for generic client.
- Aim at high cohesion and low coupling.
- Aim at low fan-out. Your class should not depend on a large number of classes
(seven or less).
- Aim at high fan-In. Your class should have high number of classes that use it. This
means that your code makes good use of utility classes.
- Prefer aggregation over inheritance.
Design The Database
- Study and understand the application domain: what data is stored and for
what purpose.
- Identify your data tables. Most often a table corresponds to a class.
- When a table corresponds to a class, fields correspond to data members,
records correspond to objects.
- Follow proper database normalization guidelines. Your database should be at
least in 3rd Normal Form.
Put It In Practice: Create a Dummy (Mock) User Interface
First determine what are the highest priority items on your list of features.
To accomplish the high priority items which classes and files must be
implemented? Once you have a tenative list of features, list the basic classes
you will need to complete the program. Make sure you know which data items are
associated with each class and which functions are needed for each class. Once
you have this you can design a user interface that you beleive meets the needs
of the user. Create a mock-up of the interface, with a menu item or action
button for each of the processes in the priority list. Make sure you call any
dialog boxes that will appear when you call a menu item or press an action
button. This allows the user to see if you are gathering and/or displaying the
information needed in an appropriate form.
After the user is satisfied, you can develop the program by creating
scenarios for each menu item and each action button. These scenarios are for
functions in the interface, but will determine if you have forgotten any
functions in the design of your application classes. From the scenarios you will
learn what other classes are involved in this operation and what functions must
be defined for these other classes. Do not overlook the initialization of the
dialog boxes and the creation of new application objects from the information
retrieved from a dialog box. If you have three people working on classes used in
an interface function, you must coordinate all inforamation needed by each
person. The design should be fairly firm before you write any code or you will
spend most of your time trying to undo what you did earlier.
Make sure you know how the various parts of the program will communicate, and
where the action take will place.
Issues To Keep Track Of
- If one object is changed, will other objects change as a result?
- Will interfaces have to change to reflect changes in an object? If so,
which ones?
- Can you create a mediator to receive messages from the classes and send
messages to other classes to indicate changes that are needed?
- Changes are best stored in the application classes since windows messages
have a fixed format that will not hold changes.
Communicate with the client frequently, showing features that have been
completed and getting feedback. This accomplishes two things. First, the client
has confidence that progress is being made and will not bug the programmers.
Second, the programmers get regular feedback, so they are more confident they
are heading in the right direction, or catch problems early on so they don't get
out of hand. Set up regular meetings with the client, so the programmers know
that on a given day of the week or month, a segment of the program must be
complete. Also set up a regular time for groups to get together to insure that
their programs can communicate.
Additional Design Issues
- Each programming group should be responsible for one part of the final
project
- Include a dummy function for each of the application functions, so the other
programmers can call on any function they need and the program will compile.
Have dummy functions pop up a message box saying the function will be finished
later.
- Make sure each application function returns a string that can be used by
the interface to indicate the result of the operation. This will ensure that the
application can be moved to another type of operating or windowing system. The
dummy functions should return dummy strings so if they are called we know they
are dummys.
- Look for classes you have already built to see if they can be reused.
- limit the depth of your hierarchy to four levels. A wide shallow tree is
preferable to a narrow deep tree.