Rob Kraft's Software Development Blog

Software Development Insights

Archive for the ‘Code Design’ Category

Robert’s Rules of Coders: #4 Make Functions Short

Posted by robkraft on August 18, 2015

Functions are easier to understand and thus easier to maintain when they are short.  You can often make functions shorter by finding patterns in a large function and extracting those lines of code comprising the pattern into a separate function and calling the separate function as shown below.

One Long Function

One Long Function

One Short Function With The Same Results

One Short Function With The Same Results

Note: The FormatForOutput function is not shown because I believe you can figure out what it does.

But even when you have a long function with no lines of code that are duplicated, you can often make the code more readable and easier to maintain by separating the code into functions.  Consider this example:

One Long Function

One Long Function

Long Function Broken Into Short Functions

Long Function Broken Into Short Functions

Note: The 4 new functions are not shown because I believe you can figure out what they do.

Most developers will be able to understand the 2nd example better than the first.  But there is another big benefit that applies in a lot of languages.  Let’s assume that an error occurs with a message of “Object variable is null”.  In the first example, the error message might show a call stack that says our program named Program1 called the method MainCodeBlock and this error occurred within MainCodeBlock.

Call Stack from First Example:

  • Program1
    • MainCodeBlock

But which line of code within MainCodeBlock?  We don’t know and it could have been caused by many of the lines.  However, if the same error occurs in the second example, our call stack would look like:

Call Stack from Second Example:

  • Program1
    • MainCodeBlock
      • SavePriceToDatabase

In the second example, we have narrowed down the problem to the SavePriceToDatabase method and have only a few lines of code to consider as the source of the error.  This is another benefit of smaller functions.

Finally, for those of you that write unit tests as most good programmers should, you have functions neatly wrapped up and ready to be called by those unit tests.

In summary, short functions provide these benefits:

  • They organize your code, making it easier to understand and maintain.
  • They make it easier to pinpoint bugs when you have a call stack.
  • They make it easier for you to write unit tests for your code.

Go to Robert’s Rules of Coders for more.

Posted in Code Design, CodeProject, Coding, Robert's Rules of Coders | Leave a Comment »

Robert’s Rules of Coders: #3 Use Good, Meaningful Names

Posted by robkraft on August 6, 2015

Code is much easier for humans to read when the variable and function names reflect what they mean and do.  In ancient times, like the 1960s, some programming languages did not support long variable names, but today most every language supports long names with no penalties.  Although some exceptions may be tolerated for very common usages such as the variables “I”, “j”, and “k” for loops, you should strive to use meaningful names in all cases.  Would anyone honestly say that the first block of code below is easier to understand than the second?

Code with and without good names

Code with and without good names

Good, meaningful names not only make your code more readable, but they may also remove the need for you to add comments or documentation to the code.

When we first began writing javascript in the 1990s we used short variable names because we wanted to reduce the size of the files to make them faster.  Today, you should probably not do this because the data is compressed by default by technologies like gzip, and Internet speeds are faster, and if you are writing enough code that the size of your javascript is a factor you should be using a minifier tool to make the javascript smaller for you.

Aside from long names, what makes a variable or function name good?

  •  Good names reflect the value stored in the variable or explain what the function does. “Counter1” is better than “c”, but “ActionCounter” is even better. Giving variables relevant names reduces the time it takes people in the future looking at the code to figure out what it does. And that includes the future you. This applies to function names also. A function named “UpdateActivityCount” is better than “CountUpdater”.
  • Try not to use negative logic in variable and function names. It takes our brains a little longer to deduce the meaning of negative logic statements.
    • IsValid is usually a better name than IsNotValid
    • DoesValueExceedMaximum is usually better than DoesValueNotExceedMaximum
  • Follow the conventions of the language you are coding in. If the language uses CamelCase, you should use CamelCase. If the language uses Hungarian Notation (txtFirstName, intItemCount), you should use Hungarian notation. If the language uses all upper case for the names of CONSTANTS, you should use all upper case for CONSTANTS too.
  • Don’t reuse variable names for different purposes.
Example of Reusing a Variable

Example of Reusing a Variable

  • The function name should describe what it does not how it does it.  This allows you to change how the code in the function works without needing to change the function name. This helps the function remain a black box.
    • Name the function GetAllCustomers, not CallDatabaseUsingADOtoGetDataFromCMCUSTTable.
  • Avoid names that might match keywords. Naming a variable “Name” or “Date” might compile safely at first, but it might fail after an update to the language is installed, or if you include a new library in the project. Also, it may not be obvious to other developers that the variable name is one that you created instead of one that is built in.
  • Follow a consistent pattern
    • If your Foo object has a Retrieve method to get data from the database, then your Bar object should also have a Retrieve method to get data from the database, not a Get method. Using the same method and property names across objects when the methods serve the same functions reduces the learning curve for new developers.
    • You should also strive to use consistent noun and verb pairings.  Naming two functions CalculateLastSaturday and CalculateLastSunday is usually easier for programmers to remember than having one function named CalculateLastSaturday and the other named FigureOutFinalSunday.

Finally, remember to rename your variables if the meaning of the value they store changes and rename your functions if the things the function does changes.  We are writing code for humans, not for computers.

Are there any more good rules that should be added to this list?

Posted in Code Design, CodeProject, Coding, Robert's Rules of Coders | Leave a Comment »

Robert’s Rules of Coders: #2 Avoid Global Variables

Posted by robkraft on August 2, 2015

Global variables are variables that can be accessed from anywhere in the program.  It is appropriate to use a global variable when you have a value that is a constant and thus won’t change as the program runs, but it is rarely appropriate to use global variables for values that change while the program is running.

Functions should usually return the same output when given the same inputs.  Global variables in functions can cause the function to return different values, making the function less reliable and more difficult to write unit tests for.

A Bad Program With Global Variables

A Bad Program With Global Variables

In the block of code above, you can see that the value returned from CalculatePrice() is not predictable.  In the first case it returned 11.00, but in the second case it returned 10.50 for the same inputs.  Here is a second version of the program:

Same Program Without Global Variables

Same Program Without Global Variables

The second version of the program has the following advantages:

  • The programmer can see all the factors that affect the TotalPrice.  None are hidden.
  • The programmer can write unit tests against the CalculatePrice() function more easily.
    • Assert.That( CalculatePrice(4, $2.5, 10%) = 11.00)

The problems with using global variables include the following:

  • Global variables can be modified from anywhere in the program, making the output of functions using them less predictable
  • Rules that you code in one place about setting the value of a global variable may not be adhered to in other places. For example one block of code may do this:
Setting Global From Spot 1

Setting Global From Spot 1

But another block of code in the program may do this:

CodeArt2-4

Setting Global from Spot 2

  • A function or component that uses global variables becomes “tightly coupled” to the other components that use the global variable.  This entanglement increases programmatic complexity which means the program is probably more difficult to maintain and enhance, and also that it is difficult to replace one component of the program without affecting others.
  • In multithreaded programs, global variables may not be thread-safe.
  • In some languages, global variables make it difficult to add new components to an existing program because the new component may contain its own global variables with the same name.

When you have an object that you think should be global so that it can be used everywhere, you should probably use Dependency Injection.  Don’t be deceived by the Singleton pattern for a global variable replacement because that often becomes just a more complicated version of a global variable.

Posted in Code Design, CodeProject, Coding, Robert's Rules of Coders | Leave a Comment »

Robert’s Rules of Coders: #1 Write Subroutines Profusely

Posted by robkraft on August 1, 2015

Most programming languages support the concept of a subroutine.  A subroutine is a block of code that your current code calls (aka executes) to run some more code.  Subroutines are called by many different names, with some of the most common being ‘function’, ‘method’, or ‘procedure’.

Subroutines serve two primary purposes:

  1. They allow you to easily reuse some of your code
  2. They organize your code, making it easier to read and maintain.

A program without subroutines

A Program Without Subroutines

A Program Without Subroutines

A program with subroutines

A Program With Subroutines

A Program With Subroutines

The advantages of the program that uses subroutines include:

  • The code is easier for another person to read, and that other person could be the future you.
  • Code that is re-used provides these benefits
    • You spend less time writing code because you can use code that already exists, the subroutine that you wrote.
    • The subroutine is already proven to work when used the first time.  You won’t have to spend time fixing logic errors and typos each subsequent time you want to do the same things.
    • If you discover a bug in the subroutine you can fix it in the subroutine which fixes it for all places from which it is called. In the first program above, if you found a bug formatting Item1PriceOut the same bug would probably also exist in formatting Item2PriceOut and need to be fixed there too.
    • If you decide something should be changed, such as using “<strong>” instead of “<b>” when formatting your string you can make the change once instead of making it in several places.
    • You can optimize the code later. Perhaps you later learn that you can call ConvertToDollars() and the formatting to two decimal places will be handled for you. You can make the change in the subroutine instead of making the change several times as you would have to do in the first program above.
Easily Change a Subroutine

Easily Change a Subroutine

  • The subroutine is more likely to be testable from an automated test.  Many languages allow you to write “unit tests” that can be run regularly to insure your code keeps working as intended even after you make changes to it over time.  It is easier to unit test code isolated in a subroutine than it is to unit test code that is just part of a larger code block.
    • Example Unit Tests:
      • Assert.That( FormatForOutput(7) = “$7.00”)
      • Assert.That( FormatForOutput(7.1) = “$7.10”)
      • Assert.That( FormatForOutput(555) = “<b>$555.00</b>”)
  • The size of the code is usually smaller when using functions, taking less disk space.
  • The size of a compiled version of the program is probably smaller, taking less disk space.
  • The size of the program in memory is probably smaller, using less RAM.
  • The memory allocated to variables is more likely to be re-used which therefore requires less RAM.

Use Subroutines Profusely

I recommend using subroutines when you see that you have two or more lines of code that are the same over and over in the program.  One thing that makes a programmer a good programmer is the ability to see patterns.  So even though these lines of code are not the same, a good programmer will see that there is a pattern and extract that pattern into a subroutine:

Can You See A Pattern?

Can You See A Pattern?

Becomes

Pattern Implemented in a Subroutine

Pattern Implemented in a Subroutine

In this case, the second program has more lines of code, but if you need to modify Item3PriceOut and Item4PriceOut the program with subroutines will become the shorter program.  And it will be easier to maintain.

Use Subroutines to Hide Complexity and Third Party Dependencies

Use subroutines for anything that might change and is used more than once, especially third party dependencies.  For example, if you use a third party tool called 123Logger in your code like this:

3rd Party Code Inline

3rd Party Code Inline

Replace it with code like the following because if you ever want to change to a different logger than 123Logger, you will only need to change your code in one place.  You are writing your code so that it is not as dependent on how the third party logger software needs to be called.

3rd Party Code in a Subroutine

3rd Party Code in a Subroutine

When you decide to use XYZLogger instead of 123Logger, you can change your code to look like this:

Using Different 3rd Party Code

Using Different 3rd Party Code

There are even better ways to handle third party dependencies like this for larger applications, but this approach is a good start.

Posted in Code Design, CodeProject, Coding, Robert's Rules of Coders | 1 Comment »

Advantages of Pure Functions and Idempotent Functions in .Net

Posted by robkraft on June 28, 2014

Summary

This article will define a “Pure Function” and an “Idempotent Function”. It will also explain the advantages of each type of function using examples in C# .Net.

Definitions

A method is a “Pure Function” when it always returns the same results when given the same inputs.  This method is a “Pure Function”:

An Idempotent method

This method is not a “Pure Function”:

A method that is not Idempotent

“Idempotent Functions” have two slightly different definitions.

  • In much of computer science, an “Idempotent Function” is a function that always returns the same result when given the same input and can include calls to methods that retrieve data from a database and also calls like HTTP GET and HTTP DELETE.  Methods that can be called repeatedly that will return the same result are “Idempotent”.

 

  • In “Functional Programming”, “Idempotent functions” are more like “Pure Functions” that go a step further. In “Functional Programming”, if you take the output of an “Idempotent function” and call that function again using the output of the last call as the input for the next call, you will get the same result again. Here is an example of using an “Idempotent Function” named abs:

var x = abs(-3); //x = 3

var y = abs(x); // y = 3

The result of calling abs(-3) is 3.  And that is the same result as calling the abs(abs(-3)).

More succinctly:

abs(abs(x)) = abs(x)

Apology

I previously wrote an article that I titled “Advantages of Making Your Methods Idempotent and Static in C#“, but I misunderstood idempotent. My article was really about “Pure Functions”, not “Idempotent Functions”. So in this article I attempt to make amends for putting something untrue on the Internet.  I want to think Phil Atkins in Cambridge, UK for patiently and persistently helping me to realize the error in my original article.

Advantages of Pure Functions

When adding methods to classes, many developers spend little time deciding if the method should be a pure function. Making use of the properties in the class causes the method to not be a pure function, as in this example of the method named ReturnNumberOfDaysSincePersonWasBorn:

Here is the ReturnNumberOfDaysSincePersonWasBorn method re-written to be a pure function:

A method that is not Idempotent

And here is another version of the method that is not a pure function. This time, the method is not a pure function because it is changing the value of a variable (Age) scoped outside of the method.

Here are the advantages to methods that are pure functions:

  • The methods are easier to maintain. They are easier to maintain because a developer needs to spend less time analyzing the impacts of changes to the method. The developer does not have to consider the state of other inputs that are used in the method. When considering a change to a method that is not a pure function, the developer must think about the impact on properties used in the method that were not passed in.
  • The methods are easier to test. When writing a unit test, it is easy to pass values into the method and write the test to verify the correct output. But writing tests on methods that are not pure functions take longer and are more complicated because more setup or injection of values is necessary for the test.
  • The methods are easier to re-use. You can call the method from other places in the module, or call the method from several different modules easily when the method is a pure function.
  • The methods are easier to move to other classes. If you have a pure function in one class and you want to move it to a utility class to be used by other modules, it is easy to do so.
  • The methods are more likely to be thread-safe. Pure functions don’t reference variables in shared memory that are being referenced by other threads. Caveat: variables such as objects that are passed by reference could still experience threading problems when used inside of static methods that are pure functions.

Resist the Temptation!

When you encounter a case like the one below, where Method3() needs the BirthDate for a calculation, it can be tempting to change the methods from static to be non-static and to reference the BirthDate property in Method3(). The other alternative is to pass the BirthDate into Method1(), and from Method1() to Method2(), and from Method2() to Method3(). Although we don’t like to make those changes, doing so allows keeps the method as a pure function and keeps the advantages provided by pure functions.

Resist the Temptation to Lose Idempotency

In C# .Net, if you are unable to mark your method “static”, then it is probably not a pure function. If the method makes database calls, API calls, updates properties outside of the method, or uses variables that have scope outside of the method, then it is not a pure function, but it may still be considered idempotent according to the non-functional definition of idempotent.

Advantages of Idempotent Functions

If you are not a functional programmer and you define idempotent functions as “functions that always return the same result for specific inputs”, then the benefits of idempotent functions are the same as the benefits of pure functions, except when they involve retrieving or update data in locations outside the function.  I rarely think about idempotent functions from a functional perspective, but idempotent functions do provide the following benefits to intelligent code compilers.

  • In some languages, if a compiler recognizes that calling abs(abs(abs(abs(x)))) will always return the same results of abs(x), it can substitute abs(abs(abs(abs(x)))) in the written code with the more efficient abs(x) in the compiled code.
  • In some languages, if a compiler recognizes that a function is idempotent, it may be able to cache the result of the call to the function and provide the cached value in place of making calls to the function again with inputs previously used.

In functional languages, the primary advantages of idempotent functions do not apply to the developer writing and maintaining code, but rather to the compiler and performance of the program.

 References

http://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning

 

Posted in Code Design, CodeProject, Coding | Leave a Comment »

Advantages of Making Your Methods Idempotent and Static in C#

Posted by robkraft on June 22, 2014

THIS ARTICLE IS INCORRECT

I apologize for putting incorrect information on the Internet.  This article explains “Pure Functions”, not “Idempotent Functions”.  I have written a new article to provide a more accurate description of “Idempotent” and also “Pure Functions” here:

https://csharpdeveloper.wordpress.com/2014/06/28/advantages-of-pure-functions-and-idempotent-functions-in-net/

My thanks to Phil Atkins in Cambridge, UK for making me aware of my error.


Read the rest of this entry »

Posted in Code Design, CodeProject, Coding | Leave a Comment »

The Correct Way to Re-Throw An Exception – .Net Tip

Posted by robkraft on March 6, 2013

When catching and re-throwing an exception, you should include the original exception as a 2nd parameter.  Including the original exception may provide a deeper stack trace that will assist you with solving the exception.

This syntax may not include the full stack trace.

This syntax may not include the full stack trace.

In the code above, if an error occurs in methodWithoutCatch(), the call stack returned will show “methodWithTryCatch” as the deepest method in the stack.

System.Exception: Additional Error Info: blah blahObject reference not set to an instance of an object.
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 34 at WindowsFormsApplication6.Form1.button1_Click
This example will include the full call stack.

This example will include the full call stack.

However, if you include the original exception in the throw as shown in the second throw example, then the call stack returned will show “methodWithoutCatch” as the deepest method in the stack.

System.Exception: Additional Error Info: blah blahObject reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at WindowsFormsApplication6.Form1.methodWithoutCatch(String z) in ...\Form1.cs:line 40
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 29
--- End of inner exception stack trace ---
at WindowsFormsApplication6.Form1.methodWithTryCatch(String y) in ...\Form1.cs:line 35
at WindowsFormsApplication6.Form1.button1_Click

Including the original exception as the second parameter of your new exception provides you with a better call stack.  In this example, it allows you to determine that the error occurred in the methodWithoutCatch method.  In the first case, you are left wondering if the methodWithTryCatch really caused the error, or if one of the three methods it called (method1, methodWithoutCatch, or method3) caused the error.

Posted in Code Design, Visual Studio 2005, Visual Studio 2008, Visual Studio 2010 | 1 Comment »

Use BCrypt to Hash Your Passwords: Example for C# and SQL Server

Posted by robkraft on October 9, 2012

By now you know passwords should be stored using a hash.  Given your decision to do the right thing and hash your passwords you still have to decide some implementation details.

First, choose a hashing algorithm.  Choose BCrypt.  Why BCrypt?  I’ll give you two reasons:

  1. It is slow, and slow is good because it thwarts brute-force attacks (read more here: http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage).
  2. The output from BCrypt is a Base-64 alphabet (http://tools.ietf.org/html/rfc4648#section-4) which means there are no characters that are tricksy to store in a simple character field; CodePage is irrelevant.

Second, find a reliable implementation of BCrypt.  I am going to show an example of using C#.Net and SQL Server, but here is a good reference I found using  PHP and MySQL (http://oscarm.org/2012/6/using-bcrypt-store-passwords).  I also say a “reliable implementation” because there are flaws in some implementations, such as one discovered in 2011 and discussed in these articles (http://en.wikipedia.org/wiki/Crypt_(Unix)http://www.digipedia.pl/usenet/thread/16234/200/ (Search for $2y$) in this second article. – $2y$ indicates you are using a version of BCrypt for Unix that does not contain this bug).

I am using Derek Slager’s C# implementation of BCrypt downloaded from here:
http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx.  Based on a little testing I did myself, I believe it does not contain the flaw cited in the above article, but I am no expert at this.  Even if the bug discovered in 2011 exists in this implementation of BCrypt, it is of little concern to me as all of my users are located within the U.S. and are extremely unlikely to be using password characters that cannot be directly entered from a standard keyboard (characters with ASCII values greater than 127).  And even if a user does have such a password, the attack vector remains incredibly tiny for exploitation.

Third, understand the inputs and outputs.  BCrypt includes a method to generate a salt.  When the salt is applied to the password, the resulting hash holds the original salt and the hashed password.  You can store the salt and password combined in a CHAR(60) field in your database.  You don’t need to store the hashed password separately from the salt, nor should you, since the BCrypt class contains a method that expects the salt and password combined to be passed in as a parameter when later confirming the correctness of the user-entered password.

Note, the salt always begins with something like $2a$10$ meaning version 2a of BCrypt and 10 rounds of computations.  10 rounds is the default.  You can choose larger numbers to make it slower, or smaller numbers to make it faster, but 10 is a really good choice for most of us.  Since the rest of the salt is 22 bytes, and the $2a$10$ is 7 bytes for a total of 29 bytes, the hashed password is always the remaining 31 bytes.  The total length of the output that you will store in the database is always 60 bytes long.

string myPassword = "password";
string mySalt = BCrypt.GenerateSalt();
//mySalt == "$2a$10$rBV2JDeWW3.vKyeQcM8fFO"
string myHash = BCrypt.HashPassword(myPassword, mySalt);
//myHash == "$2a$10$rBV2JDeWW3.vKyeQcM8fFO4777l4bVeQgDL6VIkxqlzQ7TCalQvla"
bool doesPasswordMatch = BCrypt.CheckPassword(myPassword, myHash);

Each password stored will have a different salt, and every time a user changes their password you will generate a new salt for the user.  I also encourage you to add a little hard-coded salt to the password.  This hard-coded salt adds a little more challenge to brute force attacks from hackers that steal your database, but have not stolen your code and don’t have the hard-coded salt.

private void SetPassword(string user, string userPassword)
{
   string pwdToHash = userPassword + "^Y8~JJ"; // ^Y8~JJ is my hard-coded salt
   string hashToStoreInDatabase = BCrypt.HashPassword(pwdToHash, BCrypt.GenerateSalt());
   using (SqlConnection sqlConn = new System.Data.SqlClient.SqlConnection(...)
   {
     sqlConn.Open();
     SqlCommand cmSql = sqlConn.CreateCommand();
     cmSql.CommandText = "UPDATE LOGINS SET PASSWORD=@parm1 WHERE USERNAME=@parm2";
     cmSql.Parameters.Add("@parm1", SqlDbType.Char);
     cmSql.Parameters.Add("@parm2", SqlDbType.VarChar);
     cmSql.Parameters["@parm1"].Value = hashToStoreInDatabase;
     cmSql.Parameters["@parm2"].Value = user;
     cmSql.ExecuteNonQuery();
   }
 }

private bool DoesPasswordMatch(string hashedPwdFromDatabase, string userEnteredPassword)
{
    return BCrypt.CheckPassword(userEnteredPassword + "^Y8~JJ", hashedPwdFromDatabase);
}

Another reference to BCrypt compared to SHA512:
http://stackoverflow.com/questions/1561174/sha512-vs-blowfish-and-bcrypt
.

Posted in Code Design, CodeProject | Leave a Comment »

Use Root Cause Analysis for Defect Prevention in your Software Development Process

Posted by robkraft on February 5, 2012

Recently I decided to review all the bugs we fixed in our last release to determine if they originated from a few common causes.  In software development, there is not a lot of data that can be mined that may provide insight into actions to take to improve software development, but I thought this might be one.  We fixed about 40 bugs in the last release, and I can tell you right now that my analysis has not lead to any significant changes in the way we develop software.  This is not because we didn’t find areas that could benefit from improvement, it is just because, in our case, attempting to make improvements to reduce the source of the bugs is not currently more valuable than other tasks we can be working on.

Of the bugs we found, I considering them to be “coding flaws”,  “configuration flaws”, “design flaws”, “process flaws”, or “requirements flaws”.  I realize that my technique is crude and I have very little data to draw definite conclusions from, but this is an exercise that anyone on a project team can perform if you are tracking the defects fixed in a release.  You may find patterns that help you identify aspects of software development most in need of improvement.  An excellent paper based on a lot of software development data at NASA is online here: http://www.hpl.hp.com/hpjournal/96aug/aug96a2.pdf.  The goal of the study in the paper, and my goal is well, was to use this “root cause analysis” to determine ways to prevent and reduce defects in the software.  Given that excellent article provides much more detail than I enter into here, I recommend that you read it if you are really interested in improving your development processes through root cause analysis of your bugs.

I will add here, a list of reasons that I came up with for the sources of bugs in our code:

18% – Coding Flaws.  The programmer did not think the issue was a bug, or the programmer did not test the issue thoroughly, or the programmer felt it was insignificant and lacked the time to address the problem.

39% – Coding Flaws.  The programmer should have noticed the problem.  But perhaps senior developers or business analysts should have provided a junior developer more training and input so that the junior developer would have recognized this as a problem.

3% – Coding Flaws.  The bug is a bug in 3rd party software we use (in this case Microsoft), that we need to wait for them to fix, or rewrite the feature.

5% – Coding Flaws.  The programmer should have just provided an error message to the user that is easier to understand.  Perhaps the message provided should always be determined by a business analyst.

5% – Coding Flaws.  A known bug was released.  The bug had minor impact and the cost to fixing it was high, as was the cost of delaying the release.

8% – Configuration Flaws.  We use code generation for much of our code.  The business analysts made mistakes that led to improperly generated code.

5% – Design Flaws.  The design did not allow for a feature to work as it needed to in some situations.

8% – Process Flaws.  We don’t test 100% of the User Interface possibilities in our application because the time required makes it impractical.  However, such testing is unnecessary for most of the code as long as we follow our processes for development.  In a few cases, we failed to follow the correct processes.

3% – Requirements Flaws.  The developer was not aware that the feature was desired.

3% – Requirements Flaws.  The requirements provided to the developer were incorrect.

3% – Requirements Flaws.  We removed a feature from the software that we thought was not being used, but it was and we had to re-add it.

We also improved performance in the last release.  Another way to phrase that is that we fixed performance problems.  It is difficult to decide if improving performance is fixing a bug or not when it doesn’t violate a clear service level agreement.  A code change is not always objectively a bug fix or an enhancement.  If the client believes it was in the original specification, the client will say the missing feature is a bug; but if the developer thinks the feature was not in the specification, then the developer will consider the addition of it in the next release to be an enhancement.  Just part of the joys of software development.

Posted in Code Design, CodeProject, Process, Project Management | 10 Comments »

Reduce Waste During Software Development by Increasing Communication

Posted by robkraft on January 16, 2012

Lean software development focuses on reducing waste. One source of waste is time spent implementing a difficult solution when the product owner would have been satisfied with a simpler solution. The likelihood that this source of waste occurs increases as the interactions between developer and product owner decreases. When the environment discourages frequent communication between product owner and developer, and the developer discovers some minor features will be more difficult than expected, the developer is likely to attempt to implement the solution as the product owner requested it. But when the environment encourages frequent communication, the developer is more likely to let the product owner know that a specific feature is more difficult than anticipated, but that the same feature goals could probably be achieved with an alternative implementation. This allows the product owner to decide if the alternative implementation is sufficient, or if he wants to pay the extra time to have the feature as originally envisioned.  A few of the factors that can contribute to an environment that discourages developer to product owner communication include:

  1. Physical distance. For several reasons, physical distance discourages communication. Developers don’t want to interrupt the product owner, and it is difficult to know if the product owner is currently in a meeting, or involved in other activities when the product owner is not visible.
  2. Personal perception. Developers don’t want the product owner to think they are unable to make decisions themselves, and may be concerned the product owner will gain that impression if the developer is frequently asking for product owner input.
  3. Unfriendly product owners. Developers quickly sense when product owners are getting annoyed with questions. Once a developer feels he has used his allowance of goodwill, he is more likely to just attempt to implement difficult solutions per the original spec rather than suggest an alternative.
  4. Introverted developers. Some developers simply prefer to minimize interactions with people they are not extremely comfortable with. When faced with the choice of interacting with a person they aren’t comfortable with, or trying to make the software work as originally requested, they frequently choose the latter.

It does not matter whether you develop software using Lean (Kanban), Agile, or Waterfall. If you can increase communication between the product owners and developers, you can probably reduce or eliminate this source of waste.  Product owners pay the price of this waste, and they are also best positioned to reduce the problems I mentioned above.  Product owners, at least the people that make the detailed decisions about how the software should work, should strive to make themselves constantly accessible to software developers.  When a developer comes with a question, the product owner should treat the developer as a welcome interruption, not as an inconvenience.  Product owners can also improve the relationship with the developer by engaging with the developers on social, non-work, levels.  This fosters a growth in trust between product owners and developers and increases the odds that developers will come to the product owner when the potential exists to eliminate waste.

Posted in Code Design, CodeProject, Coding, Process | 4 Comments »