Tuesday, August 9, 2011

Informative not flame-ative debate on VB vs C#

http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/vb-net-isn-t-c

Thursday, July 14, 2011

Monday, June 20, 2011

Crazy Outside the box thinking

I have an idea that is really way out there beyond conventional thinking today: every method could potentially be its own class.

For example, lets consider this method:

private decimal ComputeTotalTax(decimal total)
{
return total * TAX_RATE;
}

We could refactor that method to be a class:

public class ComputeTotalTax
{
public decimal TaxRate { get; set; }
public decimal Amount {get; set;}
public decimal Tax { get { return TaxRate * Amount;}}
}

It does the same thing right? Is there any reason why we don't do this more ?

I can think of a few:
  1. Lazy programmer syndrome. It's much easier to stick with what we have been trained.
  2. Who thinks about code like that? Its much easier to stick with our experiences led us to do since we started programming.

Any others?






Sunday, July 12, 2009

The cost of code

I've come up with a new theorem in software engineering, well I think its a new one. Here it is:

The older the code base, the more it cost to maintain the code.

Let me explain: In the first year I build a product. In the second year I add new features but do not make any changes to the existing code. I repeat this step 4 years. The oldest bit of code is4 years old therefore my code base is 4 years old. Now assume a competitor starts at the same time I do. But in year two, he refactors code written previous year. He repeats these steps each year. At the end of 4 years, his code is 1 year old.

Who's code is probably easier to make changes to? My competitor's code base would be easier.

Why do I think that would be the case?
  1. Engineering staff tends to turn over about every 18 months, which leads to product knowledge loss for each turn over. One of the hardest challenges of bringing on new staff is over coming the learning curve of the product internals. Refactoring code keeps the logic fresh in the minds of especially of the engineers, but also in quality, product management and support teams.
  2. New paradigms and best practices tend to come around about the same period. Part of the reason for staff turn over is engineers want to do new things. Refactored code will tend to done using latest programming paradigms and best practices. And the practice of refactoring the code allows for the engineering staff to grow their skills without staff turn over.

Here is a real life example: for about 7 years I worked on a commercial software package. The code base was literally 15 years old or older. We had a practice that we did not change code that worked.

One of the application windows had a button that would print out software installation and statistic information intended to help support staff diagnosis application problems. We called it the Tech Support Sheet. This code had not been changed in several, if not more, years. Support had been asking for updates to the Tech Support Sheet for years. Finally, it was updated.

The engineer that made the changes found some existing code that would provide the details requested in the Tech Support Sheet. So logically, he added calls to get the new information, but made no other refactoring changes to the print out code. After the product shipped, support reported it did not work. Why?

Turns out there was option to have the Tech Support Sheet generated when you started the program. The new code the engineer included in the print out code required some initialization that did not occur until well after the program started. But when the Tech Support Sheet was called at program startup, the initialization had not occurred. No one caught it until it made it out into the field.

There's is a lot of pieces to this puzzle for this event to occur. However, I feel pretty confident that if the start up code and the Tech Support Sheet code had been refactored from time to time, there is a lot more likelihood this problem would not have happened as the relationships between these subsystems would have been more fresh in the staffs thinking.

Wednesday, February 4, 2009

Carelessness is dangerous

Today I encountered a very odd situation. When I opened the solution, an entire solution "tree" (folders and projects) were missing from the solution. The solution compiled with no errors. I only happened to notice because the work I wanted to do was in the removed projects.

A couple of circumstances makes this error very curious:
  • the "deleted" projects where consumers of existing projects. That's why the solution still compiled.
  • this was only a solution file change. The project code and binaries still existed on my system. Since these projects ran as services, the services still functioned.
I started digging into the history of the solution changes in source control. Turns out someone checked in the solution that in error removed these folders and projects. And it was carelessness that checked in this change. What alluded me to that?

The check in comment was "not sure why this is checked out".

The engineer, seeing the solution was checked out, just assumed it needed to be checked in. This mistake is a big one. Because of it's nature, it was caught quickly.

Imagine a smaller case. A small change in a file--such as an accidental removal of a line of code. The change is a bug but who knows when that bug will be found. More times often than not, after the code reaches production.

It is of the utmost importance that developers just don't check in code. They know what they are going to check in. And they are certain the changes are suppose to make it into the source.

Always review the changes before making a check in. It will save you time, and frustration.

Wednesday, November 26, 2008

Time is your most precious resource

Time is the most precious resource we have as engineers. There is only so much we can achieve in a given time span. And everything we intend to do requires time more than any other resource.

It's safe to say that just about everyone recognizes this fact. Where many people, maybe most people, struggle making time wisely choices. When time gets tight, the choices usually made end up costing more time, in the long run.

A rule of thumb I've learned over the years is a shortcut is only a shortcut today, payback comes tomorrow.

A good example of how this plays into the software development life cycle is the shortcuts developers take with code when under pressure--and almost always the wrong kind of shortcuts: cut and paste code, leaving out commenting for later, skipping unit tests, breaking development standards and practices etc.....

Yet in the end, these types of shortcuts are the most expensive shortcuts to take!

As a rule, changing functionality, fixing a defect, or even refactoring code costs more the longer the functionality has been in place. Why?

Among other things, Co-dependency and Lost Knowledge:


Code doesn't live in a vacuum

Code rarely lives in a vacuum. It co-exists with other code, building on the pieces of the project. Code that depends on other code which happens to contain defect may very well break when the defect is fixed as the dependent code may have made certain assumptions or considerations based on the defective code.


Lost Knowledge

The intent, the purpose and all of the decisions that go into how code is engineered is most memorable when it was first written. As time passes, memories fade. Recovering these faded memories takes time. We all strive for good documentation (yet it is one of the first victims of the lack time). But let's face it, rarely does one go back to document after the code has been delivered.


Short cut example:

I'm in a rush and I find some code similar to my needs. Rather than taking the time to make a solution work for both the existing solution and my new new solution, I cut and paste the code. My solution is in place and saved me some time. Saved me some time until a bug comes around or a requirement changes. In most cases only one instance gets changed and the other is forgotten until later (and how many times does this happen when time is already very tight).

Bottom line is most shortcuts do not save any time or reduce stress, in the long run. So, you're better off doing it right upfront. Develop habits and skills (and even tools) that make it easier for you to do it right even under pressure. The pay back will be better quality, less stress and more meaningful work.

Wednesday, November 19, 2008

Some outside the box intelligence

Check out the IT blog by Buu Nguyen. Very much worth spending some time reading his thoughts....

Monday, September 22, 2008

Comments should address why, and even how rather than what

The other day I was standing with my boss and another colleague reviewing his work on some code templates. The code he generated looked a lot like this:

// check for null
if (record == null)
throw new Exception("record cannot be null");

My boss made the statement that there was no need to comment every if statement. Developers should only have to comment logic that is not obvious.

The problem I’ve seen with this thinking is developers cannot distinguish what is not obvious when they are writing the code. At the time of writing the logic, it is obvious. The knowledge is lost when the code is checked in.

My boss was prompted to what he said because the comment in the example above is completely useless. Comments need to provide value to the reader.

The real question is why is null a problem? And even how can a consumer of the code correct the problem? Let's take a look at an updated example:

// we expect the record to be initialized by
// the caller as there is not enough information
// to adequately determine which record could
// be loaded if the record was null.

if (record == null)
throw new Exception("record cannot be null");

What does the new comments tell the reader? A null record instance is bad because the code below will not be able to initialize the record instance. The error can be corrected by the consumer passing in a valid record instance.That comment is a lot more meaningful.I’m not saying its a perfect comment, but it’s a lot better.

Every logic branch should be commented. Comments need to focus on why and how. It save a lot of bugs and no doubt saves a lot of time as well.