Rob Kraft's Software Development Blog

Software Development Insights

Archive for September, 2011

Here is why we write poor quality software.

Posted by robkraft on September 8, 2011

The problem:
You need to read the value of a property that is in a class in another project.  The property scope is internal making it inaccessible to your class.  Do you do the right thing?

Writing quality software implies that you are making the correct coding decisions.  But a lot of factors may induce us to make an incorrect decision.  In this example, any of the following may happen:

  1. The developer simply changes the property scope to public because the developer is under a lot of pressure to complete the task as quickly as possible.
  2. The developer simply changes the property scope to public because the developer is a junior developer and doesn’t even conceive that this may not be the best thing to do.
  3. The developer simply changes the property scope to public because the developer assumes that the internal scope of the property must be an unintentional error.
  4. The developer simply changes the property scope to public because the developer believes himself to be a great developer and he sees a quick resolution to the problem and implements it.  Great developer status confirmed once again.
  5. The developer simply changes the property scope to public because the developer morale is low and the developer is not concerned with the quality of the software.  Besides, it is unlikely any negative impact of this change will be realized and thus attributed to the developer.
  6. The developer simply changes the property scope to public because he talked to other developers or the lead developer/architect and they determined that the internal scope was either in error or unnecessary.
  7. The developer uses the InternalsVisibleTo feature to make the property accessible to his class because the developer understands that we may desire to keep the property scoped internal, and the developer is familiar with this technique for accessing internally scoped properties.
  8. The developer uses the InternalsVisibleTo feature to make the property accessible to his class because the developer talked to other developers or the lead developer/architect and they determined that using InternalsVisibleTo was the best way to preserve the desired internal scope.
  9. The developer has his code make a call to the database to get the same value that the other class’s property would have returned because he is very comfortable writing code to make database calls and writing SQL and is less comfortable with these ideas of object-oriented programming.
  10. The developer has his code make a call to the database, or uses a different business object because he talked to other developers or the lead developer/architect and they determined that the property and class he originally intended to use for the value were not the best/correct way to obtain this value.

From the ten options I provided above, there are basically three different ways to write the correct code, but only one correct answer.  Do you see the three different ways to write the code?  Do you see the correct answer?  The three different ways to write the code are:

  1. Change the scope of the property to public,
  2. Use the InternalsVisibleTo feature to access the property,
  3. Find an alternative solution to the problem that does not use the internally scoped property.

But there is only one correct answer, and the correct answer is to take the time to do the research to determine the correct answer.  I worded it as “the developer talked to other developers or the lead developer/architect and they determined” in each case.  Of course, the developers familiar with the architecture can probably choose the correct solution without consulting their peers, any developer that makes a decision without knowing the architectural reasons is only going to get it correct if they are lucky.

Side note: the true correct approach is the one that gets it right in the least amount of time; therefore it
would be any approach that does not take time to consult peers or consider the architecture, but just happens to be lucky enough to get it right anyway.

This article is not an article about classes and properties.  It is an article about some of the ways that code quality deteriorates.  The specific example is provided for clarity, especially for .Net developers.

  1. In the first case above, the developer succumbed to time pressure and possibly chose an incorrect resolution for the problem.  I suspect time pressure is a major source of low quality code.  Developers often understand that a better solution may be available, but that time is required to evaluate alternative approaches.  The approach taking the least amount of time is the approach they already can see how to implement.  Furthermore, it is sometimes more important to implement a feature incorrectly and get it to production and fix it later than it is to delay the release in order to implement the feature correctly the first time.  Developers often see that the solution they are implementing may not be ideal, but that it is good enough and that you may discover after several days of analysis that the unanalyzed first approach was the correct approach anyway.  When poor quality code enters production to meet a deadline, the quality failure is partially the responsibility of the developer because he should push back on the time pressure before writing code of poor quality; but it is also the responsibility of the lead developer or architect to make sure that quality is not lost in critical places, and it is also the responsibility of the product owner and project manager to allow the software to meet all requirements, not just time schedule, but also quality levels.
  2. In the second case, the developer simply lacks experience or is unaware.  I don’t know of any steps a person can take to become aware of what they are unaware of.  This is why developers coding in new languages, paradigms, and architectures should have mentors, pairing partners, and code reviews.  This quality failure occurs due to a flaw in the software development process, not the developer.
  3. Case three and four both occur when the developer believes he already knows the answer.  This is why “Knowledge is the greatest barrier to learning.”  If you think you already know the answer, you will not think to look for a better solution.  This quality failure is primarily the fault of the developer, but it is partially the responsibility of the team lead to understand the nature of this developer and the possible flaws that the developer is prone to; especially if the developer is young and inexperienced.  It is also possible that development processes, particularly some unit tests or static analysis, could identify specific incorrect alterations to the code.
  4. Case five occurs when the developer is dissatisfied with the company, or his career with the company, or with the particular project, with other developers on the team, or possibly even with aspects of his life outside the work place.  Both the individual developer and the company are responsible for employee morale.  I think some people make the mistake of claiming that the morale is the full responsibility of the company, but I disagree.  I believe that the company is a primary contributor and needs to address morale as a top priority; but most of us know people that will be unhappy and complain no matter how well they are treated.  Morale could be the most important contributor to quality code.  When your employees are engaged in the software and feel ownership for the software and when they know the end-user clients and how the software helps them, the employees are more likely to strive to provide quality software.  But when employees are treated as a necessary and expensive component on an assembly line that cranks out software to anonymous people, they are less likely to be concerned about the quality of the code.
  5. Case seven is very similar to case three and four.  A little knowledge is a dangerous thing.  Developers with some experience learn multiple ways to solve the same problem, but they may still not understand which implementation to use for specific scenarios, and thus they may choose the wrong one.  This quality failure is the responsibility of both the developer and the lead developer/architect.  Developers that are aware of a choice to be made, but are not totally sure which option to choose, should ask the lead developer for clarification.  It is also the responsibility of the lead developer to let other developers know that he is receptive to such questions, and it is the responsibility of the architect to educate developers about the goals and priorities of the architecture so that developers have the knowledge to make the correct decisions on their own.
  6. Case nine is similar to case two, but this usually applies to developers with years of experience writing code a certain way that are now faced with writing code in ways they are not as familiar with.  These are often senior developers with a good understanding of the business domain and business needs and they can envision many solutions to the problem, but they have not bought into some of the priorities of the architecture.  Getting developers to change their ways after years or decades of developing working solutions using other techniques is certainly a challenge, and the responsibility for making sure these developers write quality code falls on the shoulders of both these developers and the team leaders.  Team leaders need to provide education to these developers about the benefits of doing things a different way.  Senior developers need to be open to trying things a new way, and accept developing more slowly during their learning curve in order to eventually see the benefits of the new approach.

On a final note, some people may wonder why I chose such a trivial problem for my example, and two responses spring to my mind.  Primarily, I chose this because it is a real-world example that I think most .Net developers can easily understand.  Secondarily this could result in a major problem if the internally scoped property contains sensitive data like a social security number or credit card number.  It is some of the smallest and most minor changes that often open security vulnerabilities in software that was previously regarded as secure.


Posted in Code Design, CodeProject, Coding | 2 Comments »

A Junior Developer’s Perception of Code Complete.

Posted by robkraft on September 4, 2011

Junior developers often think they have successfully completed coding a feature when they test the feature and it works for them.  Experienced developers are not so quick to consider their task complete.  Experienced developers are aware that a working feature specifically means that it works on their development platform, but before the feature is truly done, more aspects should be evaluated.

  • Does it work on other platforms? (Both 32 and 64 bit Operating Systems?, Multiple OS versions such as both Windows XP and Windows 7, multiple browsers such as IE9, IE8, FireFox 4, and Chrome)
  • Is the code secure, does it open risks for SQL Injection, XSS, or other attacks?
  • Does the code perform well under all expected conditions, such as when there is a lot more data in the database or multiple users?
  • Does the source code follow the patterns of the other source code in the project/development shop?
  • Does the source code pass StyleCop and FXCop tests?
  • Does the code have unit tests covering it adequately and do those tests all pass?
  • Is the code easy to maintain, support, and enhance?
  • Finally, most importantly, does the code do what the customer wants?

Posted in Code Design, Coding | 1 Comment »