Wednesday, July 28, 2010

Babies are Like Software

Ordinarily I wouldn’t do this, but I have a new lady in my life.

IMG_0490 

And, although this may be a bit of a stretch, this is a blog about Zen Coding, so I will try and find a way to relate babies to software, specifically non-Agile and poorly designed software:

  1. They require constant supervision, nurturing, and maintenance
  2. They acquire “bad smells
  3. They are completely un-testable
  4. They do not communicate effectively
  5. They come with long-term maintenance costs
  6. You build for 40 weeks and don’t see the result until the end

But, they are very cute. My wife and I want to thank you everyone for the cards, flowers, cookies, and congratulations.

Wednesday, July 21, 2010

Where’s the Talent?

I ran across this article by Mike Gold the other day that asks the rhetorical question “where did all the designers go!”. He raises some good points about our profession (most of which I happen to agree with). This is an excerpt from the opening paragraph:

As a consultant, you often find yourself looking at other people's code. That is because you are often asked to finish an existing product, or to make an existing product work correctly.  One of the most frustrating aspects of inheriting preexisting code is that invariably the code was written with only rudimentary consideration of the design process. "How can that be?", you wonder. "I thought all software programmers are designers by nature."  If you believe this, you've swallowed the biggest myth of all time. Software developers are rarely designers. In fact, I have come across so few real software designers over the years that I ask myself, who is even creating the software products for our industry? What has caused this dearth of design talent in the industry?

The sad reality and underlying theme in all of the author’s reasoning is mediocrity of expectations. It never ceases to amaze me the garbage clients are willing to put up with and pay for, without complaint out of some obligatory respect to the developers. That is one of the reasons our industry is so rife with amateurs and hobbyists – the great yawning chasm of accountability. It is our responsibility to demand better from ourselves and our colleagues. I think it is time for those of us who see this as an offense to our profession to rise up and go Full Metal Jacket on the Private Pyle developers of this world.

Wednesday, July 14, 2010

Single-Responsibility Principle

Introduction
Of all the SOLID design principles, this one may be the easiest, in theory, to adhere to. It also exposes some subtleties that the inexperienced eye may miss allowing rot to take a foothold in our code.

The Single-Responsibility Principle (SRP) is “officially” defined as the functional relatedness or cohesion of elements in a class. To my eyes, this is a rather broad definition. Uncle Bob refines this a little stating that “a class should have only one reason to change”. How do we classify or identify a “reason to change”?

When we move away from a data-centric view of design and begin to recognize our code from a more anthropomorphic and metaphor driven perspective, we begin to see emergent behaviors. Analysis of behavior gives us a keener sense of motivation for changing a class or method. If we can find more than one force exerting pressure to change our code, then it must be refactored to separate out those responsibilities or reasons for change. This can be at a class or method level.

Examples
Here is a very simple example that violates SRP:

public void SRPViolation(Contract contract)
{
if (contract.ExecutionDate == null ||
(!contract.ExpirationDate == null &&
contract.ExecutionDate > contract.ExpirationDate))
{
//contract is not valid
}

else if (contract.ExecutionDate <= DateTime.Now &&
(contract.ExpirationDate > DateTime.Now ||
contract.ExpirationDate == null))
{
//contract is current so do stuff
}
}

There are several problems with the above method. First, it does not effectively communicate. Second, it has two reasons to change. The first if statement defines some validation rules. The second defines a “current” contract. These are business rules and are one of the most volatile aspects of our code. Let’s start refactoring and improve the quality of the code.

We will start by introducing an IValidator interface and move the validation logic into a concrete ContractValidator class:

public interface IValidator<T>
{
void Validate(T item);
bool IsValid { get; }
}

public class ContractValidator : IValidator<Contract>
{
private bool isValid;

public void Validate(Contract item)
{
isValid = true;

if (item.ExecutionDate == null ||
(item.ExpirationDate != null &&
item.ExecutionDate > item.ExpirationDate))
{
isValid = false;
}
}

public bool IsValid
{
get { return isValid; }
}
}

Next we will move our “current” contract logic to the contract class, as this logic is unlikely to change (I know the word “unlikely” is suspect, but if the requirements change we can always refactor):

public class Contract
{
public DateTime ExecutionDate { get; set; }
public DateTime? ExpirationDate { get; set; }

public bool IsCurrent
{
get
{
return
this.ExecutionDate == null ||
(this.ExpirationDate != null &&
this.ExecutionDate >
this.ExpirationDate);
}
}
}

Now our updated method looks like this:

public void SRPRefactored(Contract contract,
IValidator<Contract> validator)
{
validator.Validate(contract);
if (!validator.IsValid)
{
//contract is not valid
}
else if (contract.IsCurrent)
{
//do stuff
}
}

This code is starting to shape up, but there is still room for improvement.

Believe it or not, if…then…else can be a violation of SRP because we are creating branching logic that can introduce another reason for change to our code. Let’s refactor this one more time:

public void SRPRefactored(Contract contract,
IValidator<Contract> validator)
{
Validate(contract, validator);

if (contract.IsCurrent)
{
//do stuff
}
}

private void Validate(Contract contract,
IValidator<Contract> validator)
{
validator.Validate(contract);
if (!validator.IsValid)
{
throw new InvalidOperationException();
}
}

Conclusion

The Single-Responsibility Principle is relatively easy to grasp, and conceptually the simplest to begin putting to use right away to improve the quality of your code.

I hope this article has given you some new insights into the Single-Responsibility Principle, and inspired you to put these ideas to use in your own code.

Wednesday, July 7, 2010

Houston TechFest

I am pleased to announce that I have been confirmed as a speaker at Houston TechFest 2010.

For more information visit their website at http://www.houstontechfest.com/dotnetnuke/default.aspx