Saturday, December 24, 2011

Try.Catch.Crap! Getting a string safely without repeating yourself

One thing that comes up a lot is when/where to write try/catch blocks.

When trying to follow DRY, it's often frustrating when you need exactly the same value but in scenario 1 you want the getter to throw if the value is not available, but in scenario 2 you want a default value if the value is not available. I had just such a situation yesterday.

Are Your Activities Making You Smart in a Google World?

KQED recently did a show: Is Google Making Us Stupid? This interview got me thinking... Whether you agree or disagree, there is little doubt that heavy use of the internet changes how you think. You can feel it happening.

Cost of GUIDs as PK...greatly exaggerated

The cost of using GUIDs as a primary key in your DB can be quite high if your DB grows to tens of millions of records, especially if you use random GUIDs. However, the dangers of these practices have been greatly exaggerated and fear mongering from some respected DBAs has caused concern among some developers. So much so that many would NEVER use a GUID as a primary key.

Below, you’ll see that, if use properly, the performance difference between integers and GUIDCOMBs is less than 10%.

Thursday, June 23, 2011

Could not find this item. This is no longer located in [some-location]. Verify the item's location and try again...

Cause: Plugging a USB 2.0 drive into USB 3.0 ports.

My friend and I recently got this message while trying to move some files on to his new laptop using a USB 2.0 external hard drive:

Could not find this item. This is no longer located in [some-location]. Verify the item's location and try again.

It turns out that his laptop (a Dell XPS) has USB ports on the back and along the side. The ports on the back of the machine are USB 3.0 and the ports on the USB 2.0.

Our problem was solved by plugging the USB 2.0 drive into the USB 2.0 ports along the side.

Thursday, May 19, 2011

What is Software Architecture and How Can We Share It?

An instructor friend recently asked me for tips on how to introduce his students to his bag of architectural best practices.  This wily old veteran of the software trenches is well aware that he has a multifaceted challenge on his hands.  He knows that it is hard to talk about architecture yet it's important for his students to understand.

Let’s start by agreeing on what software architecture is, at least what it is in this conversation.

Clements and Kazman define architecture as:
"...the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them.   Architecture is concerned with the public side of interfaces; private details of elements - details having to do solely with internal implementation - are not architectural."
This definition resonates with me because it scales to the very small and the very large.  It also makes it clear that when you create a public element you are making an architectural decision.  This fits whether we are building an API, a set of web services, a class, or an output variable in a function.

This definition also includes one of the most important parts of architecture - the relationships among the elements.   More specifically, “relationship” refers to dependencies between elements.   Experienced developers know that the single most important thing you can do to keep your software agile and maintainable is to understand and manage the dependencies.


Wednesday, April 13, 2011

Quality Starts Small: Removing Null Checks

This is a good example of how to remove null checks in your code. Null checks make your code harder to understand and add little value. Don't misunderstand me, for code to have any quality at all it must handle null values well. However, to make your code more maintainable and reliable it can be advantageous to code in a style that doesn't litter your code with null checks. Refactoring the source of your null to it's own function is one way to handle this issue and I've illustrated this technique below.

Null checks may also represent code that is trying to do too much (SRP). Quality is hard to ensure if a function has multiple responsibilities. Checking for null in the middle of your function probably represents defensive coding to protect against a reference which was given to you as null and not a proper instance of whatever type you were expecting. If you move responsibility for dealing with the null to it's own function your code will become cleaner. Cleaner code is easier to understand and maintain.

The code below uses the excellent .Net XElement utility class. This class rocks. When you ask for a sub XElement, the design is to return null and not throw an exception if the sub XElement you've requested can't be found. This is a reasonable choice for a utility, but it may not be what we want to live with in our code.

The code below is part of a an .Net XElement wrapper for parsing XML and it requests a sub XElement called "Deployments." This is the source of the null value that we want to get out of our code.

There are many ways to handle a null value and this example shows just one.  The context for this example is that we are calling an API which is returning null and we are forced to defensively code around the null value but null itself has no meaning to us - we would prefer an empty element.   This may not always the case and you would probably need another solution.  In our case, we want to perform the same functions whether the node is a fully populated XElement or an empty one.
We need to refactor the following code with a null check:

private IEnumerable GetDeployments()
{
    var deployments =  new List();
    var deploymentsElement = Node.Element( Namespace + "Deployments" );
    if( deploymentsElement != null )
    {
        var deploymentsNode = new DeploymentsNode( deploymentsElement, Namespace );
        return deploymentsNode.ExportAsDeployments();
    }
    return deployments;
}

The reason for the null check is that Node.Element(Namespace + "Deployments" ); can return null.

If you factor that code out into a function like this and instead of having it return null we return an empty "Deployments" XElement that we create, our original code can use it without concern for null checking:

private XElement GetDeploymentsNode()
{
    var deploymentsElement = Node.Element( Namespace + "Deployments" );
    return deploymentsElement ?? new XElement( "Deployments" );
}
 
You can then update the original function to remove the null check and it looks like this:

private IEnumerable GetDeployments()
{
    var deploymentsNode = new DeploymentsNode( GetDeploymentsNode(), Namespace );
    return deploymentsNode.ExportAsDeployments();
}
 
The refactored code, with null handling hidden inside a method looks like this:

private IEnumerable GetDeployments()
{
    var deploymentsNode = new DeploymentsNode( GetDeploymentsNode(), Namespace );
    return deploymentsNode.ExportAsDeployments();
}  

private XElement GetDeploymentsNode()
{
    var deploymentsElement = Node.Element( Namespace + "Deployments" );
    return deploymentsElement ?? new XElement( "Deployments" );
}
 
Which is much easier to understand and maintain than the original code.

(Obviously this is sample code: You wouldn't want the hard coded strings in your final code and it would all need to be wrapped in a try/catch. This example illustrates a specific technique for removing null checks and does not represent production quality code. Thanks)

Saturday, March 19, 2011

Why is discussing architecture so hard?

In my previous post I outlined a few of the ways that application architecture fits with the Agile values.  In this post, I attempt to outline some of things that make it tough to get everyone on the same page architecturally.

As an architect I've noticed a curious thing over the years.  Most of the issues I face in software have to do with the lack of sound architectural principles or the tangled mess of monolithic style applications strung together by not following SOLID object-oriented principles.  (I include much of what I've written in the past in that mess.)  However the first thing you hear when you mention architecture is a fear that the application will be "over architected."  (This is also often confused with the term "over engineered.")  I suggested creating one class this week in a meeting and was met with, "well we don't want to over architect this."  Yikes!

Why the fear of over architecting when so much software is so poorly designed in the first place?   It didn't make sense until I had a conversation with my friend Eric.  He mentioned that if you can't visualize the architectural solution in your own head, then it just becomes an impediment.   You just can't get down that path from where you are.  And it may make you feel stupid.

No one wants to feel stupid, especially not smart people and software people are almost all smart.  No one likes to feel as if they don't know how to do something.  Talking to someone who is not an architect about architecture has a tendency to make them feel stupid.  I've noticed that even software architects don't go around talking too much about architecture.

Looking back on it, most of the time when I've heard the fear of "over architect-ing" mentioned it was followed by comments like "I can do this faster without (that)" or "that's just in the way" or "I don't understand why we need that."   I could never reconcile that with the promise of design patterns (remember: a design pattern is a solution to a problem in a context).  Applying design patterns within a solution should make you go faster, not slower.  They certainly shouldn't be more "in the way" than they are helpful.  In fact, they should allow you to talk about and refactor large chunks of functionality with ease.  More importantly, they should communicate what they do and how it might be tested.

I've watched the same developer that expressed concern about too much architecture struggle with the lack of structure.  With chaos that is barely manageable.  I've watched them struggle to go fast with so many tangled dependencies and interwoven responsibilities plaguing their objects.  I've watched them struggle with where to put concepts and ideas as the requirements change.   I've watched them be forced to use debugging to get their code into submission as the immediate feedback from QA is a string of bugs they didn't expect but which were completely predictable.

While watching all this, I'm convinced that these developers don't connect their struggles with the cause.  They'll often say things like, "Well that changed," or "no one could have predicted that" or if they are talking to non-technical people they will just mention the technical reasons for the issue.   A break when reading a feed will be blamed on it's structure, and while technically correct, the rejected architectural components which would have made adjusting to the change is rarely brought up.   

I think part of the problem is that when you first introduce most architectural style changes they do get in the way.  Most architecture is meant to prevent a problem that you don't have yet.  When you are building a house you often have a stage where you put up a ridge support of some kind.  These "ridge" beams tend to run the entire length of the building and are usually extremely heavy.  Putting up the ridge beam tends to be very hard to do.  Often it's even followed by a little celebration.

After you put in the ridge beam, it looks sorta stupid.  Here you have this huge beam, basically floating in the air supporting nothing.  Even after the walls are put on, it seems a waste.  But everyone knows it's not.  They know it holds the house together and that when all the roofing, insulation and heating components are installed, a sturdy beam like that will be a benefit, a structural requirement even.

Well, the first day you decide to move a set of classes into a control layer, or a domain layer, or a persistence layer, or a UI layer, or a services layer the added infrastructure is going to look and feel like that ridge beam sitting out there for no reason.   At this point (for the first few days or a few weeks on larger projects) it is extra, you probably could go faster without adding it.   But unlike the ridge beam, not everyone can envision it's necessity down the road.   The comment above that "I don't understand why we need it" is a killer.  And it's not just the architecture that's at risk, the success of the project is at risk.  If the efforts to put structure behind the chaos are undermined, the chaos to follow will bring the software to it's knees like a building without a ridge beam.

So that's the chasm we are trying to cross.  On one hand, Agile, RAD, and solid architecture go hand in hand.  On the other hand, some developers aren't ready for design patterns, application layering, and constant refactoring.  It threatens them because before you can refactor, you have to see at least a hint of where you want to go.  Before you can layer, you need to understand the sort of things that might share a layer - you also have to understand how the layers will stitch together and why the constrains they allow are a good thing.  You have to understand that layering is one of our few lines of defense against the chaos of dependencies.   As communicators of architecture the architects need to understand that talking about it can make smart people feel stupid.   It's tough.

It may be tough, but if we want to be RAD, do Agile, while still creating quality software we have to find a way to cross the chasm.

Suggestions?

Where does application architecture fit in the Agile/Rad landscape?

The Manifesto for Agile Software Development states:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

Lets look at these one at a time.

Individuals and interactions over processes and tools

Developers are human and humans are social animals.   From a process point of view, when we come together as a group to review architecture, I've noticed that it's one of the most interactive parts of the software development process.  The debates are lively and the conversations are usually friendly and robust.  So, having architectural discussions is a great way to stress individual opinion and group interaction.

A primary tool in architecture development is the design pattern.  Design patterns were inspired by Christopher Alexander, the father of the modern pattern language view of architecture.  By establishing and using design patterns, a
dvocates (...) claim that ordinary people of ordinary intelligence can use it to successfully solve very large, complex design problems.  When you use a design pattern, you are applying an architectural solution.

Working software over comprehensive documentation

This one is interesting.  It says you should spend your time writing and creating working software rather than creating comprehensive documentation.  However, it is not an excuse to not create ANY documentation.  Some of the easiest and most useful documentation can be architectural.  So, if you're trying to minimize the time spent on documentation, make an architectural drawing.  Do it quickly, include just what's important to convey your ideas and constraints, then build it in working software.

Better yet, since working software is your goal, build it and document it once, and then reuse it.   Reuse has gotten a bad name in the last decade or so because it's so hard to do it right.  However, with the NuGet packages, extension methods, and test driven development, we are finally in the position to say that if you are not creating the software you deliver by plugging-in, stitching together, and importing templates, components, and binaries from a familiar and trusted supplier (yourself in many cases), then you are costing someone time and money.

RAD originally meant (in 1991) the use of heavy prototyping as an emphasis on developing software (see Martin, et al).    However today it tends to refer to highly component-ized development using frameworks like Rails, VB, Lightswitch, etc.  (Ruby, by the way is not a RAD language, Rails is a RAD framework because of the level of scripting.)

Since our goal is to create working software we need to focus our effort.  In software we often do that by focusing on one responsibility at a time.  In object-oriented programming, this is know as the Single Responsibility Principle and it is a fundamental principle for creating software using the SOLID
guidelines.

You can write software without following these principles, but it won't be object-oriented and it won't be as maintainable as it could be.   It's also highly unlikely that it will be easy to change.  In other words - it won't be a form of RAD.   By creating clarity and focus, you create a landscape where you have individuals interacting to create working software over documentation.   Proper architecture helps make that possible.   Take a quick look at the SOLID guidelines and how many of them help guide good structure and style (architecture):

Initial Stands for
(acronym)
Concept
S SRP
Single responsibility principle
the notion that an object should have only a single responsibility.
O OCP
Open/closed principle
the notion that “software entities … should be open for extension, but closed for modification”.
L LSP
Liskov substitution principle
the notion that “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”. See also design by contract.
I ISP
Interface segregation principle
the notion that “many client specific interfaces are better than one general purpose interface.”[5]
D DIP
Dependency inversion principle
the notion that one should “Depend upon Abstractions. Do not depend upon concretions.”[5] Dependency injection is one method of following this principle.

Customer collaboration
over contract negotiation


One of the biggest values that architecture (and experience) bring in this area is that knowing the architecture helps the technical people to estimate better.  Estimation will remain as flexible as feature scope, but the closer the technical people can come to providing the customer with realistic expectations for quality, cost, features, and schedule the better the collaboration with the customer will be.

Responding to change
over following a plan

When good architectural principles (layering, components, and design patterns) are applied, then followed with sound software development practices (Lean, Agile, Scrum) and SOLID object-oriented principles are followed, the software stays flexible to change.   That's not to say that some changes won't take a long time, but it does mean that they will take a fraction of the time to change when compared to a product where these practices and principles were not followed.

These thoughts on architecture are continued in my next post about why discussing application structure and style is so hard.