CSC/ECE 517 Fall 2009/wiki3 14 12: Difference between revisions
No edit summary |
No edit summary |
||
(11 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
The Principle of Self-Documentation (aka Self-Commenting) states that "The most reliable document of software is the code itself. In many cases, the code is the only documentation. Therefore, strive to make your code self-documenting, and where you can't, add comments." [http://www.developerdotstar.com/mag/articles/read_princprog.html] With the advent of Agile Programming methodologies the need for Self-Documenting software is on the rise. Previous design methodologies (like the Waterfall Design Methodology) required the programmer to develop a design document/contract with the customer before the program is undertaken. The advent of Extreme Programming and Agile's Test Driven Design (TDD) requires the software engineer/programmer to pay more attention to the actual code written since the methodologies openly shun design specifications.[http://www.softwarereality.com/lifecycle/xp/four_values.jsp][http://jjinux.blogspot.com/search/label/agile] Extreme Programming values Self-Documentation and TDD believes that the tests are the contracts/documentation for a program to adhere to. | The Principle of Self-Documentation (aka Self-Commenting) states that "The most reliable document of software is the code itself. In many cases, the code is the only documentation. Therefore, strive to make your code self-documenting, and where you can't, add comments." [http://www.developerdotstar.com/mag/articles/read_princprog.html] With the advent of Agile Programming methodologies the need for Self-Documenting software is on the rise. Previous design methodologies (like the Waterfall Design Methodology) required the programmer to develop a design document/contract with the customer before the program is undertaken. The advent of Extreme Programming and Agile's Test Driven Design (TDD) requires the software engineer/programmer to pay more attention to the actual code written since the methodologies openly shun design specifications.[http://www.softwarereality.com/lifecycle/xp/four_values.jsp][http://jjinux.blogspot.com/search/label/agile] Extreme Programming values Self-Documentation and TDD believes that the tests are the contracts/documentation for a program to adhere to. | ||
=Tenets of Self-Documentation= | |||
Self-Documenting programs should be the goal of any [http://brajeshwar.com/2007/are-you-a-programmer-or-a-coder/ programmer]. Software that is self-documenting should be easy to read with design intent easy to understand and comprehend. Code density will be as dense as it needs to be without being too dense. Essentially it should never fail the initial "sniff" test. | Self-Documenting programs should be the goal of any [http://brajeshwar.com/2007/are-you-a-programmer-or-a-coder/ programmer]. Software that is self-documenting should be easy to read with design intent easy to understand and comprehend. Code density will be as dense as it needs to be without being too dense. Essentially it should never fail the initial "sniff" test. | ||
==Use meaningful/descriptive variable/method names== | |||
Variables are more than memory location abstractions, they are the building blocks on which the program is built. They represent some real world component that is being modeled by the program (a person's name, the force of gravity, number of doors to a room); the intent of the variable should be derived based upon its name. | Variables are more than memory location abstractions, they are the building blocks on which the program is built. They represent some real world component that is being modeled by the program (a person's name, the force of gravity, number of doors to a room); the intent of the variable should be derived based upon its name. | ||
Methods are responsible for performing actions upon the real world data abstractions. The name of the method represent the action that the method is performing. | Methods are responsible for performing actions upon the real world data abstractions. The name of the method represent the action that the method is performing. | ||
The following example set is from Stack Overflow[http://stackoverflow.com/questions/209015/self-documenting-code].<br> | |||
Example of non-descriptive code: | |||
float a, b, c; a=9.81; b=5; c= .5*a*(b^2); | float a, b, c; a=9.81; b=5; c= .5*a*(b^2); | ||
Example of Self-Documenting Code | Example of Self-Documenting Code: | ||
const float gravitationalForce = 9.81; | const float gravitationalForce = 9.81; | ||
float timeInSeconds = 5; | float timeInSeconds = 5; | ||
float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2) | float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2) | ||
Example using coherent method name | Example using coherent method name: | ||
const float accelerationDueToGravity = 9.81; | const float accelerationDueToGravity = 9.81; | ||
float timeInSeconds = 5; | float timeInSeconds = 5; | ||
Line 26: | Line 27: | ||
http://thedailywtf.com/Articles/CodeThatDocumentsItselfSoWellItDoesNotNeedComments.aspx | http://thedailywtf.com/Articles/CodeThatDocumentsItselfSoWellItDoesNotNeedComments.aspx | ||
==Use Language Constructs when Possible== | |||
Code should be readable not only to the author but to reviewers as well. Modern programming languages have been adding native language constructs to allow for additional readability. Ruby added the "unless" operator to replace the "if not" syntax. The use of List/Array iterators allows each list item to be referenced as its native name. | Code should be readable not only to the author but to reviewers as well. Modern programming languages have been adding native language constructs to allow for additional readability. Ruby added the "unless" operator to replace the "if not" syntax. The use of List/Array iterators allows each list item to be referenced as its native name. | ||
Line 42: | Line 42: | ||
The use of dictionaries (python) or hashes (perl/ruby) instead of vanilla arrays allows for elements to be referenced by native names instead of array position. | The use of dictionaries (python) or hashes (perl/ruby) instead of vanilla arrays allows for elements to be referenced by native names instead of array position. | ||
==Use Design Patterns== | |||
The use of language constructs is an intermediate level of self-documenting. The use of common Design Patterns allows for the programmer and reviews to instantly know what the design intent is. Deviates from the patterns should be documented/commented so that the reviewers know that pure patterns weren't used. Rails is a good example of the use of design patterns (MVC). Controllers typically have controller embedded in the name and file/class function are segregated via directory structure makes the code intent easy to infer. | The use of language constructs is an intermediate level of self-documenting. The use of common Design Patterns allows for the programmer and reviews to instantly know what the design intent is. Deviates from the patterns should be documented/commented so that the reviewers know that pure patterns weren't used. Rails is a good example of the use of design patterns (MVC). Controllers typically have controller embedded in the name and file/class function are segregated via directory structure makes the code intent easy to infer. | ||
Line 62: | Line 62: | ||
} | } | ||
==Comments are evil; but not pure evil== | |||
Agile programmers tend to eschew since comments are one of the first things to entropy in a code base. The feeling is that comments are rarely updated during refactoring which cause the code and comments not to match up which causes confusion[http://www.flamingspork.com/blog/2005/08/08/comments-are-evil/]. Beginning programmers forget that comments are intended to provide intent insight not exact behavior insight. | Agile programmers tend to eschew since comments are one of the first things to entropy in a code base. The feeling is that comments are rarely updated during refactoring which cause the code and comments not to match up which causes confusion[http://www.flamingspork.com/blog/2005/08/08/comments-are-evil/]. Beginning programmers forget that comments are intended to provide intent insight not exact behavior insight. | ||
# returns a bool value | # returns a bool value | ||
Line 76: | Line 76: | ||
end | end | ||
=== | =Conclusion= | ||
Agile programming practices make sense for non-mission critical applications where time-to-market is the main driving force. Limited customer requirements or moving requirements require a programming practice this is flexible and extendable. Rapid prototyping allows for the customers to have feedback and to get a "good-enough" product out to market and then iterate. Self-documenting code fits nicely with this practice since it allows for evolving code and the intent is always preserved in spite of application fluidity. | |||
=Definitions= | |||
Test-Driven Development (TDD): A style of programming where tests for a new feature are constructed before any code is written. Code to implement the feature is then written with the aim of making the tests pass. Testing is used to understand the problem space and discover suitable APIs for performing specific actions.[http://doc.silverstripe.org/doku.php?id=testing-guide-glossary]<br> | |||
Agile Development: refers to a group of software development methodologies based on iterative development, where requirements and solutions evolve through collaboration between self-organizing cross-functional teams. [http://en.wikipedia.org/wiki/Agile_programming]<br> | |||
Waterfall Design: is a sequential software development process, in which progress is seen as flowing steadily downwards (like a waterfall) through the phases of Conception, Initiation, Analysis, Design (validation), Construction, Testing and maintenance.[http://en.wikipedia.org/wiki/Waterfall_model]<br> | |||
=References= | |||
[1] http://www.developerdotstar.com/mag/articles/read_princprog.html <br> | |||
[2] http://www.softwarereality.com/lifecycle/xp/four_values.jsp <br> | |||
[3] http://jjinux.blogspot.com/search/label/agile <br> | |||
[4] http://stackoverflow.com/questions/209015/self-documenting-code <br> | |||
[5] http://www.flamingspork.com/blog/2005/08/08/comments-are-evil/ <br> | |||
[6] http://doc.silverstripe.org/doku.php?id=testing-guide-glossary <br> | |||
[7] http://en.wikipedia.org/wiki/Agile_programming <br> | |||
[8] http://en.wikipedia.org/wiki/Waterfall_model <br> | |||
=External Links= | |||
http://www.developerdotstar.com/mag/articles/read_princprog.html <br> | |||
http://blogs.agilefaqs.com/2008/11/08/self-documenting-code-example <br> | |||
http://www.clariusconsulting.net/blogs/kzu/archive/2009/10/01/171565.aspx <br> | |||
http://www.embedded.com/design/202602883 <br> |
Latest revision as of 03:37, 24 November 2009
Principle of Self-Documentation
The Principle of Self-Documentation (aka Self-Commenting) states that "The most reliable document of software is the code itself. In many cases, the code is the only documentation. Therefore, strive to make your code self-documenting, and where you can't, add comments." [1] With the advent of Agile Programming methodologies the need for Self-Documenting software is on the rise. Previous design methodologies (like the Waterfall Design Methodology) required the programmer to develop a design document/contract with the customer before the program is undertaken. The advent of Extreme Programming and Agile's Test Driven Design (TDD) requires the software engineer/programmer to pay more attention to the actual code written since the methodologies openly shun design specifications.[2][3] Extreme Programming values Self-Documentation and TDD believes that the tests are the contracts/documentation for a program to adhere to.
Tenets of Self-Documentation
Self-Documenting programs should be the goal of any programmer. Software that is self-documenting should be easy to read with design intent easy to understand and comprehend. Code density will be as dense as it needs to be without being too dense. Essentially it should never fail the initial "sniff" test.
Use meaningful/descriptive variable/method names
Variables are more than memory location abstractions, they are the building blocks on which the program is built. They represent some real world component that is being modeled by the program (a person's name, the force of gravity, number of doors to a room); the intent of the variable should be derived based upon its name.
Methods are responsible for performing actions upon the real world data abstractions. The name of the method represent the action that the method is performing.
The following example set is from Stack Overflow[4].
Example of non-descriptive code:
float a, b, c; a=9.81; b=5; c= .5*a*(b^2);
Example of Self-Documenting Code:
const float gravitationalForce = 9.81; float timeInSeconds = 5; float displacement = (1 / 2) * gravitationalForce * (timeInSeconds ^ 2)
Example using coherent method name:
const float accelerationDueToGravity = 9.81; float timeInSeconds = 5; float displacement = CalculateDisplacement(accelerationDueToGravity, timeInSeconds);
As with most things in life it is possible to go overboard on the descriptive naming convention: http://thedailywtf.com/Articles/CodeThatDocumentsItselfSoWellItDoesNotNeedComments.aspx
Use Language Constructs when Possible
Code should be readable not only to the author but to reviewers as well. Modern programming languages have been adding native language constructs to allow for additional readability. Ruby added the "unless" operator to replace the "if not" syntax. The use of List/Array iterators allows each list item to be referenced as its native name.
List iteration has move from C's:
for(int i = 0; i < list.length(); i++) { operation on list[i] }
To :
for object in list : operation on object
Or:
list.each { |object| operation on object }
The use of dictionaries (python) or hashes (perl/ruby) instead of vanilla arrays allows for elements to be referenced by native names instead of array position.
Use Design Patterns
The use of language constructs is an intermediate level of self-documenting. The use of common Design Patterns allows for the programmer and reviews to instantly know what the design intent is. Deviates from the patterns should be documented/commented so that the reviewers know that pure patterns weren't used. Rails is a good example of the use of design patterns (MVC). Controllers typically have controller embedded in the name and file/class function are segregated via directory structure makes the code intent easy to infer.
Languages like Scala have design patterns that can be inherited. The inherited functionality allows for the reviewer and programmer know how the inherited class should behave.
import scala.actors.Actor import scala.actors.Actor._ class Counter extends Actor { var counter: Int = 0; def act() = { while (true) { receive { case Inc(amount) => counter += amount case Value => println("Value is "+counter) exit() } } } }
Comments are evil; but not pure evil
Agile programmers tend to eschew since comments are one of the first things to entropy in a code base. The feeling is that comments are rarely updated during refactoring which cause the code and comments not to match up which causes confusion[5]. Beginning programmers forget that comments are intended to provide intent insight not exact behavior insight.
# returns a bool value def is_equal_to_two(value) return value == 2 end
The code doesn't need a comment since the intent of the code can be derived via the method name.
Not all comments are evil. Comments are good when they explain the why but not the how or what.
# compute displacement with Newton's equation x = v0t + ½at^2 def compute_displacement(gravitational_force, time_in_seconds) return (1 / 2) * gravitationalForce * (timeInSeconds ^ 2) end
Conclusion
Agile programming practices make sense for non-mission critical applications where time-to-market is the main driving force. Limited customer requirements or moving requirements require a programming practice this is flexible and extendable. Rapid prototyping allows for the customers to have feedback and to get a "good-enough" product out to market and then iterate. Self-documenting code fits nicely with this practice since it allows for evolving code and the intent is always preserved in spite of application fluidity.
Definitions
Test-Driven Development (TDD): A style of programming where tests for a new feature are constructed before any code is written. Code to implement the feature is then written with the aim of making the tests pass. Testing is used to understand the problem space and discover suitable APIs for performing specific actions.[6]
Agile Development: refers to a group of software development methodologies based on iterative development, where requirements and solutions evolve through collaboration between self-organizing cross-functional teams. [7]
Waterfall Design: is a sequential software development process, in which progress is seen as flowing steadily downwards (like a waterfall) through the phases of Conception, Initiation, Analysis, Design (validation), Construction, Testing and maintenance.[8]
References
[1] http://www.developerdotstar.com/mag/articles/read_princprog.html
[2] http://www.softwarereality.com/lifecycle/xp/four_values.jsp
[3] http://jjinux.blogspot.com/search/label/agile
[4] http://stackoverflow.com/questions/209015/self-documenting-code
[5] http://www.flamingspork.com/blog/2005/08/08/comments-are-evil/
[6] http://doc.silverstripe.org/doku.php?id=testing-guide-glossary
[7] http://en.wikipedia.org/wiki/Agile_programming
[8] http://en.wikipedia.org/wiki/Waterfall_model
External Links
http://www.developerdotstar.com/mag/articles/read_princprog.html
http://blogs.agilefaqs.com/2008/11/08/self-documenting-code-example
http://www.clariusconsulting.net/blogs/kzu/archive/2009/10/01/171565.aspx
http://www.embedded.com/design/202602883