|
|
|
|
|
|
|
The idea behind functional cohesion is that each module should do just one thing and do it well. Functional cohesion is not a well-defined property; there is no quantitative measure of cohesion. It is a product of the human need to organize things into neat chunks that are easy to understand and remember. Knowing which details to make concrete and which to leave abstract is a matter of experience, circumstance, and personal style. For example, you might decide to include a fieldwidth calculation in a printing module if there isn't so much detail in the rest of the module that it becomes confusing. On the other hand, if the calculation is performed several times, it makes sense to write it as a separate module and just refer to it each time you need it. |
|
|
|
|
|
|
|
|
Here's one approach to writing modules that are cohesive: |
|
|
|
|
|
|
|
|
1. Think about how you would solve the subproblem by hand. |
|
|
|
|
|
|
|
|
2. Begin writing down the major steps. |
|
|
|
|
|
|
|
|
3. If a step is simple enough so that you can see how to implement it directly in C++, it is at the concrete level; it doesn't need any further refinement. |
|
|
|
|
|
|
|
|
4. If you have to think about implementing a step as a series of smaller steps or as several C++ statements, it is still at an abstract level. |
|
|
|
|
|
|
|
|
5. If you are trying to write a series of steps and start to feel overwhelmed by details, you probably are bypassing one or more levels of abstraction. Stand back and look for pieces that you can write as more abstract steps. |
|
|
|
|
|
|
|
|
We could call this the procrastinator's technique. If a step is cumbersome or difficult, put it off to a lower level; don't think about it today, think about it tomorrow. Of course, tomorrow does come, but the whole process can be applied again to the subproblem. A trouble spot often seems much simpler when you can focus on it. And eventually the whole problem is broken up into manageable units. |
|
|
|
|
|
|
|
|
As you work your way down the solution tree, you make a series of design decisions. If a decision proves awkward or wrong (and many times it will), you can backtrack (go back up the tree to a higher-level module) and try something else. You don't have to scrap your whole designonly the small part you are working on. There may be many intermediate steps and trial solutions before you reach a final design. |
|
|
|
|
|
|
|
|
You'll find it easier to implement a design if you write the steps in pseudocode. Pseudocode is a mixture of English statements and C++-like control structures that can be translated easily into C++. (We've been using pseudocode in the algorithms in the Problem-Solving Case Studies.) When a concrete step is written in pseudocode, it should be possible to rewrite it directly as a C++ statement in a program. |
|
|
|
|
|
|
|
|
Remember that the problem-solving phase of the programming process takes time. If you spend the bulk of your time analyzing and designing a solution, coding and implementing the program will take very little time. |
|
|
|
|
|