… because everyone loves writing documentation.
widely used
McConnell has a good & balanced discussion on this.
Source code commenting is often a crutch to hide
Still useful for
Modern focus has shifted considerably away from commenting bodies towards API documentation.
double m; // mean average
double s; // standard deviation
double meanAverage
double standardDeviation
// Sum up the data
double sum = 0.0;
double sumSquares = 0.0;
// Add up the sums
for (double d: scores)
{
sum += d;
sumSquares += d*d;
}
// Compute the average and standard
// deviation
double meanAverage = sum / numScores;
double standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/(numScores - 1.0));
// Subtract the average from each data
// item and divide by the standard
// deviation.
for (int i = 0; i < numScores; ++i)
{
scores[i] = (scores[i] - meanAverage)
/ standardDeviation;
}
// Compute summary statistics
double sum = 0.0;
double sumSquares = 0.0;
for (double d: scores)
{
sum += d;
sumSquares += d*d;
}
double meanAverage = sum / numScores;
double standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/ (numScores - 1.0));
// Normalize the scores
for (int i = 0; i < numScores; ++i)
{
scores[i] = (scores[i] - meanAverage)
/ standardDeviation;
}
// Compute summary statistics
double sum = 0.0;
double sumSquares = 0.0;
for (double d: scores)
{
sum += d;
sumSquares += d*d;
}
double meanAverage = sum / numScores;
double standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/(numScores - 1.0));
// Normalize the scores
for (int i = 0; i < numScores; ++i)
scores[i] = (scores[i] - meanAverage)
/ standardDeviation;
void computeSummaryStatistics (
const double* scores, // inputs
int numScores,
double& meanAverage, // outputs
double& standardDeviation)
{
double sum = 0.0;
double sumSquares = 0.0;
for (double d: scores)
{
sum += d;
sumSquares += d*d;
}
meanAverage = sum / numScores;
standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/(numScores - 1.0));
}
void normalizeData (double* data,
int numData,
double center,
double spread)
{
for (int i = 0; i < numData; ++i)
data[i] = (data[i] - center) / spread;
}
⋮
double meanAverage;
double standardDeviation;
computeSummaryStatistics (scores, numScores,
meanAverage, standardDeviation);
normalizeData (scores, numScores,
meanAverage, standardDeviation);
void computeSummaryStatistics (
const double* scores, // inputs
int numScores,
double& meanAverage, // outputs
double& standardDeviation)
{
double sum = 0.0;
double sumSquares = 0.0;
for (double d: scores)
{
sum += d;
sumSquares += d*d;
}
meanAverage = sum / numScores;
standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/(numScores - 1.0));
}
void normalizeData (double* data,
int numData,
double center,
double spread)
{
for (int i = 0; i < numData; ++i)
data[i] = (data[i] - center) / spread;
}
⋮
double meanAverage;
double standardDeviation;
computeSummaryStatistics (scores, numScores,
meanAverage, standardDeviation);
normalizeData (scores, numScores,
meanAverage, standardDeviation);
void computeSummaryStatistics (
const double* scores, // inputs
int numScores,
double& meanAverage, // outputs
double& standardDeviation)
{
double sum = accumulate(
scores, scores+numScores);
double sumSquares = accumulate(
scores, scores+numScores,
[](double x, double y)
{return x + y*y;});
meanAverage = sum / numScores;
standardDeviation =
sqrt ((sumSquares - numScores*sum*sum)
/(numScores - 1.0));
}
⋮
// Normalize the scores
double meanAverage;
double standardDeviation;
computeSummaryStatistics (scores, numScores,
meanAverage, standardDeviation);
transform (
scores, scores+numScores,
scores,
[] (double d) {
return (d - meanAverage)
/ standardDeviation});
Repeat of the code
Repeat of the code
Useless
Repeat of the code
Useless
Explanation of the code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Description of intent
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Description of intent
similar to summary, but describes problem rather than solution
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Description of intent
similar to summary, but describes problem rather than solution
Information that cannot be expressed in the code
Repeat of the code
Useless
Explanation of the code
Only useful if the code is confusing
In which case, first priority should be to simplify the code.
Markers
notes not intended to be left in final code
If standardized, useful
e.g., // TODO
in Eclipse
Summary of the code
Description of intent
similar to summary, but describes problem rather than solution
Information that cannot be expressed in the code
e.g., authors, copyright, date of modification
Self-Documenting code relies on good programming style to perform most of the documentation.
Classes
Does the class’s interface present a consistent abstraction?
Is the class well named, and does its name describe its central purpose?
Does the class’s interface make obvious how you should use the class?
Is the class’s interface abstract enough that you don’t have to think about how its services are implemented? Can you treat the class as a black box?
Routines
Does each routine’s name describe exactly what the routine does?
Does each routine perform one well-defined task?
Have all parts of each routine that would benefit from being put into their own routines been put into their own routines?
Is each routine’s interface obvious and clear?
Data Names
Are type names descriptive enough to help document data declarations?
Are variables named well?
Are variables used only for the purpose for which they’re named?
Are loop counters given more informative names than i, j, and k?
Are well-named enumerated types used instead of makeshift flags or boolean variables?
Are named constants used instead of magic numbers or magic strings?
Do naming conventions distinguish among type names, enumerated types, named constants, local variables, class variables, and global variables?
Data Organization
Are extra variables used for clarity when needed?
Are references to variables close together?
Are data types simple so that they minimize complexity?
Is complicated data accessed through abstract access routines (abstract data types)?
Control
Is the nominal path through the code clear?
Are related statements grouped together?
Have relatively independent groups of statements been packaged into their own routines?
Does the normal case follow the if rather than the else?
Are control structures simple so that they minimize complexity?
Does each loop perform one and only one function, as a well-defined routine would?
Is nesting minimized?
Have boolean expressions been simplified by using additional boolean variables, boolean functions, and decision tables?
Layout
- Does the program’s layout show its logical structure?
Design
Is the code straightforward, and does it avoid cleverness?
Are implementation details hidden as much as possible?
Is the program written in terms of the problem domain as much as possible rather than in terms of computer-science or programming-language structures?
(McConnell, ch 32)
How many forms of software documentation charting do you know?
How many forms of software documentation charting do you know?
How many forms of software documentation charting do you know?
Flowcharts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
Structure (call) charts
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
Structure (call) charts
Data-Flow Diagrams
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
Structure (call) charts
Data-Flow Diagrams
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
Structure (call) charts
Data-Flow Diagrams
How many forms of software documentation charting do you know?
Flowcharts
Nassi-Schneidermann Charts
Structure (call) charts
Data-Flow Diagrams
For as long as people have been writing source code, they’ve been looking for ways to ease the effort of documenting that code.
Earliest examples were automatic flowchart generators
Generating flowcharts from source code.
Still offered in reverse engineering tools ( e.g. )
A hallmark of so-called CASE (Computer-Aided Software Engineering) systems
API documentation tools are now more common
Reflect modern emphasis on re-usable interfaces
Combine info from
a (limited) language parser
and specially formatted blocks of comments embedded in the source code
Encourages updating comments as code is modified
Comments become a legitimately useful tool for application writers.
Application writers have less need to access actual code.
Generate linked documents to facilitate browsing of referenced type names and other entities
Some IDEs understand this markup as well and use it enhance “live” help while editing code.
Perhaps the best known tool in this category
Javadoc markup is enclosed in comments delineated by /** ... */
A comment block precedes the entity that it describes
In addition to “free-form” text, can contain special markup
Common Javadoc Markup
@author authorName
@version versionNumber
@param name description
@return description
@throws exceptionClassName description
@see crossReference
Running javadoc
Command line
javadoc -d destinationDir -sourcepath sourceCodeDir \
-link http://docs.oracle.com/javase/7/docs/api/
Eclipse: Project
⇒ Generate Javadoc ...
Ant
Ant has a javadoc
task among its default task set.
A typical invocation might be:
<javadoc packagenames="edu.odu.cs.*"
destdir="target/javadoc"
classpathref="javadoc.classpath" Author="yes"
Version="yes" Use="yes" defaultexcludes="yes">
<fileset dir="." defaultexcludes="yes">
<include name="extractor/src/main/java/**" />
<exclude name="**/*.html" />
</fileset>
<doctitle><![CDATA[<h1>ODU CS Extract
Project</h1>]]></doctitle>
</javadoc>
Gradle
Gradle
provides a javadoc
task when you use the Java plugin. For example, if you are using my example of a simple Java build, you can run javadoc
like this
./gradlew javadoc
Here is the full build.gradle
for a simple Java build with Javadoc generation.
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
testCompile "junit:junit:4.12+"
}
test {
ignoreFailures = true ➀
}
javadoc { ➁
options.with {
links 'https://docs.oracle.com/javase/8/docs/api/', 'gradle/javadocs/jdk'
}
}
build.dependsOn javadoc ➂
javadoc
task before the build
task.the most popular API generator for C/C++
Markup is essentially identical to javadoc
Output can be HTML, LaTeX, or RTF
Can also generate
Running doxygen
Command line
doxygen configFile
PROJECT_NAME = C++ Spreadsheet
INPUT = src/model
OUTPUT_DIRECTORY = target/doc
EXTRACT_ALL = YES
CLASS_DIAGRAMS = YES
GENERATE_HTML = YES
GENERATE_LATEX = YES
USE_PDFLATEX = YES
Eclipse: Eclox plugin
Ant task for doxygen
Gradle plugins for doxygen (untried)
Because a documentation generator needs to module and function structure and function parameters, a distinct parser is needed for each programming language.
This leads to a variety of language-specific tools, e.g.,
jsDoc for Javascript
YARD for Ruby
sandcastle for .Net