April 11, 2012

Software Development Best Practices

Here are some development process best practices and their benefits. Of course, best practices are generally good ideas but are not rules.

Document While Coding

Comments explaining the purpose and operation of code should be written while coding. Special cases and unexpected workarounds should be fully explained. Functions should have their behavior, input and output parameters, return values, and any special considerations documented when declared.

  • Helps ensure design and implementation are fleshed out.
  • Encourages developers to identify edge and error cases up front.
  • Documents intention and purpose versus implementation, which prevents bugs when coding or refactoring.
  • Educates other developers about why something was implemented a specific way, which they can apply to their own code and future development.
  • Simplifies maintenance and refactoring by ensuring behaviors and functional contracts are maintained.

Refactor Now Instead of Later

When adding new code or making changes to existing code, spend the time and effort to refactor now instead of later in exchange for completing sooner. This may require you to touch more code than you would like or make minor changes to code unrelated to your specific change or feature addition. Do not copy/paste code to avoid refactoring.

  • Prevents duplicate code or logic; all duplicates need to be found in the event of a bug or feature addition.
  • Making minor changes to reuse existing code decreases the amount of new untested code.
  • Avoids duplication of effort when refactoring occurs later.
  • Leverages tests of existing code and minimizes the prevents duplicate test effort for duplicate logic.

Unit Test Before Committing

A bug fix or new feature should not be considered complete until unit tests for that code are also complete. Unit tests should exercise both correct and erroneous code paths and incorporate stress tests if possible.

  • Regression tests already exist in the event of future code changes.
  • Ensures code is functionally and logically correct before it is made available to other developers.
  • Encourages developers to identify edge and error cases up front.
  • Encourages developers to consider the use cases and usability of new code up front.

Write Functional Code

Write functional code in favor over procedural code. Functional code is where the return value and any output parameter values only depend upon the input parameter values. Procedural code depends on information other than the input parameters or has side-effects that affect other code.

  • Ensures changes to the implementation of a function do not violate the behavior expected by callers.
  • Function behavior changes require the parameters to change, forcing all callers to update their use of the function and therefore be aware of the behavior change.
  • Prevents multiple threads from accidentally interfering with each other due to shared state.
  • Functional code is by definition thread-safe.

Write Self-Contained Code

Do not require users of a library, module, or class to understand the inner workings or state of that class. This means all state must be private, memory management must be internally managed, and all synchronization must be internally implemented.

  • Prevents external code dependencies or logic from requiring changes in the event of a bug or feature addition.
  • Prevents memory leaks due to unclear ownership of allocated memory (smart pointers can be used to transfer ownership).
  • Ensures state cannot be tampered with or made accidentally inconsistent.
  • Ensures synchronization logic is properly scoped and balanced.
  • Allows modules, libraries, or classes to be declared thread-safe.

Create Immutable Objects

Immutable objects have all state information set upon construction and this information cannot be changed. Whenever possible, objects or state containers should be made immutable. Changes to state information require the creation of a new instance.

  • Guarantees internal state cannot become inconsistent.
  • Immutable objects are thread-safe.

Resource Acquisition Is Initialization

Use resource acquisition is initialization, or RAII. Acquire resources and initialize instances in constructors and release resources and cleanup in destructors.

  • Promotes exception-safe and thread-safe code.
  • Ensures initialized state before use and automatic cleanup when instances are destroyed.

Use Detailed Changelist Descriptions

When committing a code change, a detailed description of the change should be included. This description should include how the change was implemented, what problems are fixed or the new feature added, and in the case of a fix why the previous code was erroneous.

  • People can understand why the code change was done the way it was done.
  • A changelog can be produced easily from changelist descriptions.
  • Repository watchers will receive a notification email that contains all the necessary information.
  • Helps inform testing effort for the code change.
  • Educates other developers about the specific issue, which they can apply to their own code and future development.

Explain Bugs

In some cases the reporter can fully describe the root cause of a bug, but in many cases only the resulting erroneous behavior is known. When the root cause of a bug is uncovered, it should be fully documented in the bug tracker. (When appropriate, this may be handled by copying the source control changelist description into the bug tracker issue.)

  • People (including the reporter) can understand what went wrong.
  • Helps inform testing effort for the specific bug or related areas.
  • Educates other developers about the specific issue, which they can apply to their own code and future development.

Explain Non-Issues and Won't Fixes

When a bug or feature request is marked non-issue or won't fix, a detailed explanation of why it is not an problem or won't be fixed should be included. Any business or technical reasons should be included.

  • Educates developers on intended behavior or technical limitations which they can apply to their own code and future development.
  • Educates testers on intended behavior or technical limitations that can inform test efforts.
  • Prevents others from re-opening the bug or request, or filing duplicates.

Posted by josuah at April 11, 2012 8:22 PM UTC+00:00

Trackback Pings

TrackBack URL for this entry:
http://www.wesman.net/cgi-bin/mt/mt-tb.cgi/1610

Comments

Post a comment

July 2013
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Search