10.5 Documentation, Code Reviews, Peer Feedback, and End-User Feedback
Key Takeaways
- Good documentation explains a procedure's purpose, parameters, return value, and preconditions, and uses comments to explain why the code does something rather than restating what it does.
- Poor documentation practices include comments that repeat the code, outdated comments that contradict it, cryptic variable names, and leftover commented-out code.
- Code reviews, in which other developers read code before it is merged, find defects, enforce standards, and spread knowledge across a team.
- Peer feedback, such as pair programming or classmates reviewing a draft, is especially useful while learning and early in a project.
- End-user feedback from usability tests, surveys, beta releases, and bug reports reveals whether software meets real users' needs, which developers often cannot judge themselves.
What this competency asks
Two related ETS competencies:
- Be familiar with characteristics of well-documented computer programs that are usable, readable, and modular. Identify characteristics of good documentation, and identify good and poor documentation practices in context.
- Be familiar with techniques to obtain and use feedback to produce high-quality code (for example, code reviews, peer feedback, and end-user feedback). Identify situations in which each technique is useful.
Why documentation matters
Code is read far more often than it is written: by teammates, by future maintainers, by students, and by the original author months later. Documentation makes programs usable (people know how to run and call them), readable (people understand the logic), and modular (each part's contract is clear, so parts can be used and changed independently).
Characteristics of good documentation
| Element | What it contains | Example |
|---|---|---|
| Header comment for each procedure | Purpose, parameters, return value, preconditions and postconditions | See the example below |
| Explanatory comments | Why a non-obvious choice was made | // start at 1: a[0] is already the initial max |
| Meaningful names | Self-describing variables and procedures | studentCount, computeAverage, not x2 or doIt |
| Consistent formatting | Indentation and spacing that reveal structure | Required in ETS pseudocode, where indentation is significant |
| External documentation | README or user guide: what the program does, how to install and run it, examples | A README explaining the inputs a grading tool expects |
| API documentation | Generated reference for libraries (Javadoc, Python docstrings) | Documents each public method's contract |
| Change history | Clear version-control commit messages | "Fix off-by-one in findMax loop bound" |
// Returns the average of the first n values in scores.
// precondition: n > 0
// postcondition: returns a double; scores is unchanged
double average ( int[ ] scores, int n )
int sum ← 0
for ( int i ← 0; i < n; i ← i + 1 )
sum ← sum + scores[i]
end for
return sum / n // assume floating-point division (see notation note)
end average
Good vs. poor practices
| Poor practice | Why it hurts | Better practice |
|---|---|---|
i ← i + 1 // add 1 to i | Restates the code and adds noise | Comment only what is not obvious |
| A comment says "returns the minimum" but the code returns the maximum | Outdated comments mislead, which is worse than no comment | Update comments with every code change |
Variables named a, b, temp2, data | Readers must reverse-engineer meaning | Descriptive names |
| Large blocks of commented-out old code | Clutters the file and confuses readers | Rely on version control for history |
| No statement of preconditions | Callers misuse the procedure (for example, pass an empty array) | State preconditions in the header comment |
| One enormous procedure with no structure | Hard to read, test, or document | Split into well-named procedures |
| Documentation written only at the end | Details are forgotten or wrong | Document while writing code |
The goal is not "as many comments as possible." Clear names and structure reduce the need for comments, and the comments that remain should add information the code cannot express.
Feedback techniques
Code reviews
In a code review, other developers examine code before it is accepted, often through a pull request (Section 2.1).
Most useful for:
- Finding defects, security problems, and unhandled edge cases that the author overlooked
- Enforcing team conventions for style, naming, and documentation
- Spreading knowledge, so more than one person understands each part of the system
- Checking design decisions before they become hard to change
Peer feedback
Peer feedback is informal feedback from people at a similar level: classmates, a partner, or teammates.
Most useful for:
- Learning: students explaining and critiquing code deepen their own understanding
- Early drafts: catching confusing logic or naming before a full review
- Pair programming: a "driver" types while a "navigator" reviews each line in real time and suggests alternatives; the partners switch roles regularly
- Building a classroom culture where code is discussed, not hidden
End-user feedback
End-user feedback comes from the people the software is for.
Most useful for:
- Judging whether the program meets real needs, and whether it is usable and accessible (Section 11.2)
- Finding confusing interfaces, unclear messages, and missing features that developers, who know how the program "should" be used, do not notice
- Discovering problems that appear only with real data or real devices
Methods: usability testing (watching users attempt tasks), surveys and interviews, beta releases, analytics, and bug-report forms.
Matching the technique to the situation
| Situation | Best technique |
|---|---|
| Before merging a change to a shared codebase | Code review |
| A novice class is learning to write loops | Peer feedback or pair programming |
| A school app is finished, but teachers find it confusing | End-user feedback (usability testing) |
| Checking that code follows the team's naming standards | Code review |
| Deciding which features a new app should include | End-user feedback (interviews, surveys) |
The techniques complement one another. Reviews find code-level problems, peers support learning and early improvement, and end users tell you whether you built the right thing.
Which comment adds the most useful information to this line?
for ( int i ← 1; i < n; i ← i + 1 )
A school releases a new attendance app. Code reviews found no defects, but teachers report that they cannot figure out how to mark a student tardy. Which feedback technique would best reveal and address this problem?
A development team requires that every change be read and approved by another team member before it is merged into the main branch. Which benefit is this practice most directly intended to provide?