Monday, December 31, 2012

2012: A Look Back

The end of the year is always a good time to take a look back and evaluate progress.  It seems like 2012 has been a busy year for me, so let's take a look back at Things I've Done, Things I've Learned, Cool Stuff that Happened, and some Thing I Didn't Get To.

Things I've Done
Speaking
It seems like I did a lot of speaking this year.  Anyone who's heard me speak has probably picked up on how much I love it, so I try to get out to as many events as I can.  This year I presented 33 sessions at 19 events.  The events included 5 Code Camps: the 3 So Cal Code Camps, Desert Code Camp in Arizona, and the Silicon Valley Code Camp (my first time there -- wow, it's big).

The rest of the presentations were at various User Groups in So Cal as well as Arizona and Nevada.  A big thank you to all of the user groups who hosted me; I always have a great time.  (And not that I'm hinting or anything, but I'm available again this year -- just use the INETA request link on the right.)

Blogging
I wrote 54 blog articles this year (55 if you count this one).  That's the most so far.  The articles are a mixture of technical articles, book reviews, upcoming events, and answers to questions from session attendees.  I even had a couple of 5 part series articles.  It was nice to have some free time earlier in the year.  I need to make sure that I set time aside specifically for technical articles.

New Sessions
I came up with 2 new sessions this year complete with code samples and walkthroughs: T, Earl Grey, Hot: Generics in .NET and Dependency Injection: A Practical Introduction.  My goal was to come up with two sessions, and I'm glad that I had a chance to present the new topics.  Dependency Injection has been a very popular topic, and I'm sure that I'll be speaking on that throughout the coming year.

Things I've Learned
It's been a big year for learning new things.  As usual, most of my learning is just-in-time learning for whatever projects that I'm working on.  I had a chance to work on a great WPF project (I really love XAML) that uses Prism (XAML application guidance from the Microsoft Patterns & Practices team).  If you've been following my blog, you've seen my thoughts on the framework.  And if you haven't been following my blog, you can catch up here and here (short version: Prism has worked very well for this particular project).

I've also learned quite a bit about Dependency Injection both through Mark Seemann's excellent book and from experience using it myself.  I also had to do a bit of learning outside of my project requirements so that I could write the new session mentioned above.

And one of the big reasons I'm a fan of Dependency Injection is Unit Testing.  I really dug in to Unit Testing this year, and I'm surprised at how quickly I took to it.  I've used mocking and dependency injection to isolate units of code for testing.  The one thing I like most about unit testing is that I can refactor with confidence.  If there's a bit of clumsy code that needs to be reworked, I first make sure that I have good tests of the functionality.  Then when I extract methods or update algorithms, I can be sure that the code is still working as intended.  As I mentioned in an article earlier this year, I'm still not at TDD yet, but I find myself doing small bits of TDD during my coding process.

Honorable mention goes to MVVM and Tasks.  I've been buried in MVVM and doing a bit of fine-tuning to make sure that I have good separation of concerns in the presentation of my applications.  I've also dug into Tasks a bit deeper and have been learning about asynchronous calls, UI interaction, exception handling, and unit testing.  Lots of good stuff.

And 2 of the most impactful books that I read this year are Clean Code and The Clean Coder.  Clean Code has made me rethink some of the ways that I've been writing methods.  I'm starting to think smaller with more layers -- something I was reluctant to do before.  The Clean Coder has made me think more about myself as a professional -- making sure that my conduct is appropriate, that I'm clear with my communication, and that I live up to my commitments.  This is definitely a process (both the code and me), so I'll keep moving forward in both areas in the coming year.

Cool Stuff that Happened
Probably the coolest thing that happened this year was being presented with a Microsoft MVP Award.  It was a great honor to be recognized for my development community contributions, and I'm looking forward to attending the MVP summit with the goal of making lots of new MVP friends (in addition to the MVP friends that I already have).

I've been getting a bit of recognition at Code Camps as well.  At the So Cal Code Camp in Los Angeles, I had someone ask if I was giving the Design Patterns talk again.  And at the Desert Code Camp in Arizona, I had someone ask if I was talking about Lambda Expressions.  These people attended my sessions the year before and still remembered not just me, but the topics as well.  That makes me feel like I'm really making an impact with the topics that I present.

Another cool thing is that my blog is getting over 1,000 hits per month (I even had close to 2,000 in September).  That might not sound like much (and it really isn't), but it's a big increase over the 250 to 350 hits per month that I used to get.

One thing that has directed some traffic to my blog is a mention on StackOverflow (thanks for the referral, Peter Ritchie).  For some reason my articles on the BackgroundWorker component get a lot of hits.  I guess it's because I have a soft spot for that component.  I know that it will probably go away soon (it didn't get included in WinRT), but I'll hang onto it as long as I can.  It's great at what it does.

Also for some strange reason, if you Google "MVVM Design Pattern", one of my articles comes up on the first page.  That's driven a lot of traffic to my blog (which is really cool), but I'm not quite sure how I got ranked so high.  I guess I shouldn't complain because it probably won't last too much longer.

Things I Didn't Get To
There were a couple of things that I didn't get to this year, but there's always next year.  First, I was planning on getting my CTT+ certification (Certified Technical Trainer).  I'm still interesting in pursuing it, but I didn't get to it this year.

I also didn't produce any technical videos this year.  I was planning on putting together a handful of quick video tutorials on various topics (like lambda expressions and delegates) but never got around to it.  A friend recently asked me for some feedback on a video that he's producing, and I think that might have given me the kick in the butt that I need to start making my own.

A Great Year Gone -- Another One Coming
Overall, it's been a great year.  I'm learning and growing as a developer -- that lets me know that I'm still interested and haven't stagnated.  I'm still having a great time speaking and mentoring, and I love to help other people.  And it's been really great to get some recognition from the developer community.

There's a great year ahead.  I've got some exciting things lined up.  And I also have no idea what's going to happen with a lot of other things.

Take a few minutes to reflect on what you've learned this year and how you've grown as a developer.  If you're not constantly learning, then you're probably falling behind.  If you don't already attend a local User Group, find one.  It's a great way to keep in contact with other developers, to find out what's going on outside of your company, and to learn about lots of great technologies.

Looking forward to another great year!

Happy Coding!

Monday, December 17, 2012

Update on Windows 8 Guidance

Last week (Five Months In: Working with Prism in WPF), I mentioned that application guidance for Windows 8 is still pending.  As an update, Blaine Wastell published an article a few days ago with the roadmap for Windows 8 guidance: Prism on .NET 4.5 and the road to Windows 8 apps.  So, it looks like we have something to look forward to from the Patterns & Practices team in the next few months.

Happy Coding!

Sunday, December 9, 2012

Five Months In: Working with Prism in WPF

Several months ago, I put down some initial thoughts regarding Prism: First Impressions: Working with Prism in WPF.  Now that I've been working with Prism for five months, I thought it was time for a follow-up.

It turns out that my opinions haven't changed much from those first impressions.  Prism is working out very well for the project I'm working on.  Taking advantage of the modularity (and the independence of each module) has allowed us to quickly modify and add to our task workflows.  We've managed to keep good separation and isolation which has made unit testing much easier.  The navigation objects are working as expected.  And the helper objects make the code much more compact, readable, and maintainable.

Prerequisites
I have confirmed my opinion that Prism is not for beginning programmers; there are a number of intermediate topics that are necessary to understand.  What is interesting is that I have articles or presentations that are centered around these prerequisites.  I didn't plan for this, it just turns out that the topics I've written about happen to revolve around the foundational knowledge required for Prism.

Here's the list from the previous article along with links to my materials:
These articles are a good place to get started.  By understanding these topics, you will be better prepared to work with Prism in your applications.

Useful Features
In the previous article, I mentioned a number of features that I liked.  That list is still accurate.  I'll go into a little more detail on 2 of these features.

DelegateCommand
The DelegateCommand allows you to create an ICommand object with much less code.  Commanding is used to data bind to buttons in the UI.  Let's compare some code.

To implement ICommand yourself is not very complicated.  But there is a lot of boiler-plate code in a custom object.  Here's a sample command implementation (this is taken from the Dependency Injection session samples):


As we can see, there is quite a bit of code here, but we really only care about the last line (that assigns to the People property of the ViewModel).  The rest is plumbing.

Compare this to using a DelegateCommand from the Prism framework:


This allows us to do the same thing (assign a value to the People property), but we can do this with just one line of code (the DelegateCommand constructor) instead of needing to create a custom class.  The parameter of the DelegateCommand constructor is the "Execute" we want to perform ("Execute" is part of the ICommand interface).

ICommand has another method: "CanExecute".  This returns true or false depending on whether the command can be executed.  In our example, this always returns "true".  But sometimes this is more complicated -- such as if we need to check a property or run some code.  The DelegateCommand constructor takes a second parameter which is a delegate for "CanExecute".  If you do not provide one, then "CanExecute" is always true.

As you can see, DelegateCommand makes our code much more compact.  And if we don't want to use a lambda expression (or if our Execute is several lines of code), then we can use a standard delegate method instead.  The result is that it is easier to see the intent of our code.  Instead of looking through a custom command object for the Execute method, we have the code right here in the constructor (or a pointer to it in the case of a named delegate).

When you have a number of commands in the application, this makes a huge difference in the amount of code that needs to be written as well as the readability of that code.

NotificationObject
NotificationObject is another class that is provided by the Prism framework.  This class implements the INotifyPropertyChanged interface.  This interface needs to be implemented in order for data binding to work as expected in XAML.  The interface itself is not hard to implement (just a few lines of boiler-plate code).  The difference between NotificationObject and manual implementation has to do with the RaisePropertyChanged methods that are available.

When implementing INotifyPropertyChanged, you generally make a call to RaisePropertyChanged in the setter for a Property, such as this:


The RaisePropertyChanged method will alert the UI that the underlying property has been updated and that the UI should refresh the binding.  Notice that this version of RaisePropertyChanged takes a string parameter.

In contrast, NotificationObject provides a RaisePropertyChanged method that takes an Expression.  This lets us write code like this:

Your first thought might be, "I don't see much of a difference."  But there is.  Instead of using a string, we use an expression with the actual Property.  This means that we get IntelliSense when we are creating this method.  It also means we will get a compiler error if we type the property name incorrectly.  And most importantly, if we rename our property, our refactoring tools will automatically update the RaisePropertyChanged method as well.  Using properties over strings is definitely the way to go.

Nothing You Can't Do Yourself
I had an interesting conversation with someone about Prism.  He asked me what I liked about it, and I told him that I really liked the DelegateCommand.  His response was that you could create a DelegateCommand object yourself -- it's only about 15 lines of code.  And he is absolutely correct.

Prism doesn't perform any magic.  It consists of a set of helper classes and methods that you could implement yourself.  But we don't have to.  The Patterns & Practices team has implemented these for us and put them together in a package that is easy to use.

If you don't like any of the implementations, you are free to change them.  Prism comes with all of the source code (including unit tests).  So you can enhance or re-implement any of the features.  My experience is that the features are well-implemented and have met my needs.

What About Windows 8?
My one disappointment around Prism is that it looks like there won't be an implementation for Windows Store Applications.  Prism covers a lot of platforms: WPF, Silverlight 5, and Windows Phone 7.5.  The latest rumors are that there will be a different guidance package from the Patterns & Practices team for Windows Store Applications, and I have not been able to hunt down a beta or a release date at this point.

If you are developing Windows 8 desktop application with WPF, then Prism will work just fine.  But for Windows Store Applications, we will need to wait for another solution.

[UPDATE: There has been announcement regarding guidance for Windows Store Apps.  More info: Update on Windows 8 Guidance]

Wrap Up
As I mentioned, my opinion of Prism has not changed much from my initial impressions of working with it.  It has been a very good framework for my current project, and I will keep it in mind for future projects.  If you are working on fairly straight-forward applications or applications with just a few screens, then Prism may be more than you need.  But if you are working on modular or enterprise-level applications, it may be just what the doctor ordered.

Happy Coding!

Book Review: Professional .NET Framework 2.0

So, I'm a bit behind on commenting on the tech books that I've read recently.  The first is Professional .NET Framework 2.0 by Joe Duffy (Amazon link).  Note: this book is from 2006 and is currently out-of-print; fortunately there are several sellers in the Amazon marketplace how have new or used copies.

Now, it may seem strange to be reading a .NET 2.0 book from 2006 in 2012, and I would normally agree with that thought.  But this book has a few key advantages to some others.  It was recommended to me as a way to "fill in some gaps", and it has done just that.  I'm not really going to review the entire book here, just provide some comments and samples on what made this valuable to me.

Big Plus - Joe Duffy
One of the big advantages to this book is its author.  Joe Duffy was a program manager on the CLR (Common Language Runtime) team at Microsoft.  This means that he knows the internals of the CLR and not just the external APIs.  And this book provides plenty of insight into the internals, as we'll soon see.

Looking into IL
The biggest learning that I took away from this book is a better understanding of IL (Intermediate Language).  This is what the compiler generates from your C# or VB.NET code (or any other .NET language).  It is not machine code, but it has more in common with assembly language than a 3G or 4G language that business programmers generally use.  The IL will get Just-In-Time compiled (jitted) to the instructions that the machine will actually run.

Now, I've known about IL for a long time, and I've seen people who look at it.  Historically, I haven't been one to dig into it myself.  But after having Joe Duffy explain IL and how language components get transformed into IL, I've been more interested in digging into the IL to see how things are generated.

Setting up ILDASM
The .NET SDK ships with a way to look at the IL -- this is ildasm.exe (for IL Disassembler).  Here's where it's found on my 64-bit machine:

At this location, you'll find a file called "ildasm.exe".  You can run this directly, and then use the File -> Open dialog to locate a .NET assembly.  But what's even better is to add this as an External Tool in Visual Studio. Then you can just run it against whatever project you're currently working on.

To configure this in Visual Studio (I'm using VS2012, but it's the same in earlier versions), just go to the "Tools" menu and select "External Tools...".  From here, you can Add a new tool.  When you're done, it should look something like this:


For the Title, you can use whatever you'd like; this is just what will appear on the Tools menu.  The command should be the fully-qualified location of the "ildasm.exe" file.

The "Arguments" and "Initial directory" settings are a little more interesting.  Notice the arrow to the right of the text box.  This gives you a number of variables that you can choose from.  For the "Arguments" property, I chose 2 variables.  The first "$(TargetName)" is the name of the assembly that is currently active.  Note that this does not include the file extension, just the name.  Because of this, we also need "$(TargetExt)".  This will give us ".exe" or ".dll" depending on what type of assembly we are building.

The "Initial directory" setting tells us where the assembly (from the argument) is located.  In this case, "$(TargetDir)" means the output location of the file.  So, if we are in the Debug build, it will be "<project path>\bin\Debug\".

After clicking "OK", we now have a new item on our tools menu.

Using ILDASM
So, now that we have Visual Studio configured so that it's easy to get to ildasm, let's see what this looks like.  I created a very simple console application that just outputs "Hello, World!" (using Console.WriteLine).  I don't think I need to reproduce the code here ;-)

With this project open, I just need to go to Tools -> ILDasm, and it opens up the compiled assembly.  Drilling down a bit, we get to the Main method:


The name of my application is "ILDamsTest.exe", and we traverse the tree to get to the Main method.  If we double-click on the Main method, we get to the disassembled IL:


Here, we see the IL for the most basic console application.  Going through the instructions, we have the following.  First, "nop" is a "no op", meaning no operation is performed.  This is here so that the compiler can attach a breakpoint to a part of the code that doesn't perform an operation (for example, attaching a breakpoint to the opening curly-brace of the method).

Next, we have "ldstr" which loads the string "Hello, World!" onto the stack.  Next, we have a "call" that runs the Console.WriteLine method.  Note that the IL has the fully-qualified name for this, including the assembly (mscorlib) and the namespace (System).  We can see that this method takes a string argument, and it gets this from the top of the stack.  Since we just pushed "Hello, World!" onto the stack, this string will be used for the parameter.

Next we have another "nop", for the closing curly-brace, and finally the "ret" that returns from the method.

Pretty simple.  Now let's look at the same thing compiled in "Release" mode:


Notice that we've gone from 5 instructions down to 3; the "nop" instructions are gone.  The compiler removed them since we can't breakpoint into release code.

More Fun with IL
So, after I started looking just a little bit at IL, I've become much more curious about how the compiler generates IL.  For example, I like to see what code is generated by the "shortcuts" that the C# language and compiler give us.

Here are 2 equivalent blocks of code:

Now, the "foreach" loop will work on any object that implements the IEnumerable interface.  That interface has a single method ("GetEnumerator").  (Note: if you want more information on IEnumerable, you can reference the series of articles at Next, Please! A Closer Look at IEnumerable.)

So, the first block of code shows how to use the Enumerator directly (with MoveNext and Current), and the second uses the "foreach" construct.  We would expect that these two blocks would compile to the same IL.

But if we look at the IL, we find that they are not compiled to the same code.  They are close, but when  "foreach" is compiled, it is automatically wrapped in a try/finally block.  Try this yourself to see.

And so started my journey into IL and the fun behind it.  Some other interesting places to look include anonymous types (to see that the compiler does create a type with an internal name), delegates (to see what a delegate is behind the scenes), lambda expressions, and many others.  You will probably come across some compiler optimizations that surprise you as well.

Note: I won't include any links to IL references because I haven't found any good ones.  If you want the specification, you can search for "ECMA 335", with a caveat that this is the 500+ page specification document (not overly readable).  Professional .NET Framework 2.0 provides a compact reference for IL (along with a number of examples).

[Update: I found an online reference. It's not very descriptive, but it has the CIL Instructions: http://www.en.csharp-online.net/CIL_Instruction_Set.]

Wrap Up
So, even though Professional .NET Framework 2.0 is 6 years old, I found many useful things in it.  There are plenty of good topics (including a look at the Garbage Collector and also multi-threading).  As you can probably tell, I've become comfortable looking at the IL -- something that I never would have done before.  An appendix is dedicated to the IL operations so that you can parse the output of ildasm yourself.  Once you start looking at the IL, you come across all sorts of interesting things that will give you a better understanding of how the code you write gets transformed into something closer to what the machine will actually run.

This is not a resource for a beginner or someone new to C#, but it is a great way to take a deeper dive into some of the fundamentals of the .NET Framework.

Happy Coding!

Sunday, November 25, 2012

Drawbacks to Abstraction

Programming to abstractions is an important principle to keep in mind.  I have shown in a number of demos (including IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces, Dependency Injection: A Practical Introduction, and T, Earl Grey, Hot: Generics in .NET) how programming to abstractions can make our code more extensible, maintainable, and testable.

Add Abstraction As You Need It
I am a big fan of using abstractions (specifically Interfaces).  But I'm also a proponent of adding abstractions only as you need them.

As an example, over the past couple of weeks, I've been working on a project that contained a confirmation dialog.  The dialog itself was pretty simple -- just a modal dialog that let you add a message, text for the OK and Cancel buttons, and a callback for when the dialog was closed.  To make things more interesting, since the project uses MVVM, we end up making the call to this dialog from the View Model through an Interaction Trigger.  What this creates is a couple of layers of code in order to maintain good separation between the UI (the View) and the Presentation Logic (in the View Model).

This confirmation dialog code has been working for a while, but it had a drawback -- it wasn't easily unit testable due to the fact that the interaction trigger called into the View layer.  The result is that as I added confirmation messages to various parts of the code, the unit tests would stop working.

I was able to fix this problem by adding an interface (IConfirmationDialog) that had the methods to show the dialog and fire the callback.  I used Property Injection for the dialog so that I would have the "real" dialog as the default behavior.  But in my unit tests, I injected a mock dialog based on the interface.  This let me keep my unit tests intact without changing the default run-time behavior of the dialog.  If you'd like to see a specific example of using Property Injection with mocks and unit tests, see the samples in Dependency Injection: A Practical Introduction.

The Drawbacks
When selecting the right tool for the job, we need to know the strengths and the weaknesses of each tool.  This lets us make intelligent choices to confirm that the benefits outweigh the drawbacks for whatever tool we choose.  When working with abstractions and interfaces, this is no different.

We've talked about the advantages of using abstraction, but what about the drawbacks?  The most obvious is complexity.  Whenever we add another layer to our code, we make it a bit more complex to navigate.  Let's compare two examples (taken from the Dependency Injection samples).

Navigation With a Concrete Type
We'll start by looking at a class that uses a concrete type (this is found in WithoutDependencyInjection.sln in the NoDI.Presentation project).


Here, we have a property (Repository) that is using a concrete type: PersonServiceRepository.  Then down in the Execute method, we call the GetPeople method of this object.  If we want to navigate to this method, we just put the cursor in GetPeople and then hit F12 (or right-click and select "Go To Definition").  This takes us to the implementation code in the PersonServiceRepository class:
This implementation code is fairly simple since it passes the call through to a WCF service, but we can see the actual implementation of the concrete type.

Navigation With An Interface
If we use an interface rather than a concrete type, then navigation gets a little trickier.  The following code is in DependencyInjection.sln in the DI.Presentation project:


This code is very similar to the previous sample.  The main difference is that the Repository variable now refers tn an interface (IPersonRepository) rather than the concrete type.  You can see that the code in the Execute method is exactly the same.

But if we try to navigate to GetPeople using F12 (as we did above), we get quite a different outcome:

Instead of being navigated to an implementation, we are taken to the method declaration in the interface.  In most situations, this is not what we are looking for.  Instead, we want to see the implementation.  Since we have decoupled our code, Visual Studio cannot easily determine the concrete type, so we are left with only the abstraction.

Mitigating the Navigation Issue
We can mitigate the navigation issue by just doing a search rather than "Go To Definition".  For this, we just need to double-click on "GetPeople" (so that it is highlighted), and then use Ctrl+Shift+F (which is the equivalent of "Find in Files").  This brings up the search box already populated:


If we click "Find All", then we can see the various declarations, implementations, and calls for this method:


This snippet shows the interface declaration (IPersonServiceRepository) as well as 2 implementations (PersonCSVRepository and PersonServiceRepository).  If we double-click on the PersonCSVRepository, then we are taken to that implementation code:


This code shows the GetPeople implementation for reading from a CSV file.  So, there are a few extra steps to finding the implementation we were looking for, but if we know our tools (namely, Visual Studio) and how to use them, then we can still get the information we need.

There are other options as well.  Instead of using "Find In Files", we can use "Find All References" (Ctrl+K, R) which will give us similar (but not exactly the same) results as a search.  Also, if you have a refactoring tool installed (like RefactorPro or Resharper), then you most likely have an even faster way to search for a particular method.  It always pays to have a good understanding of your development environment.

Wrap Up
Everything has a cost.  In the case of programming to abstractions, that cost is added complexity and indirection when moving through source files.  The benefits include extensibility, maintainability, and testability.

As mentioned, I'm a big fan of adding abstractions as you need them.  Once you become familiar with your environment (the types of problems you are trying to solve and the parts that are likely to change), then you can make better up-front decisions about where to add these types of abstractions.  Until then, start with the concrete types and add the abstractions when needed.  Note: many times you may find yourself needing abstractions immediately in order to create good unit tests, but this will also vary depending on the extent of your testing.

For more information with finding the right level of abstraction, refer to Abstraction: The Goldilocks Principle. In many environments, the benefits will outweigh the costs, but we need to make a conscious decision about where abstractions are appropriate in each particular situation.

Happy Coding!

Monday, November 5, 2012

Coming Soon: Desert Code Camp

Desert Code Camp is coming up on November 17th, 2012: http://nov2012.desertcodecamp.com/.  If you are in the Phoenix area, be sure to stop by if you can (even if just for part of the day).  Code Camps are a great place to meet other developers and talk about what's working and what's not.  Plus, it's a full day of free training from folks in the developer community.

I've got 3 sessions scheduled:
T, Earl Grey, Hot: Generics in .NET
Dependency Injection: A Practical Introduction
IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

Hope to see you there.

Happy Coding!

Sunday, October 21, 2012

Unit Testing: A Journey

In the last article (Abstraction: The Goldilocks Principle), we took a look at some steps for determining the right level of abstraction for an application.  We skipped a big reason why we might want to add abstractions to our code: testability.  Some developers say that unit testing is optional (I used to be in this camp).  But most developers agree that in order to be a true professional, we must unit test our code (and this is where I am now).

But this leads us to a question: Should we modify our perfectly good code in order to make it easily testable?  I'll approach this from another direction: one of the qualities of "good code" is code that is easily testable.

We'll loop back to why I take this approach in just a moment.  First, I want to describe my personal journey with unit testing.

A Rocky Start
Several years back, I didn't think that I needed unit testing.  I was working on a very agile team of developers (not formally "big A" Agile, but we self-organized and followed most of the Agile principles).  We had a very good relationship with our end users, we had a tight development cycle (which would naturally vary depending on the size of the application), we had a good deployment system, and we had a quick turnaround on fixes after an application was deployed.  With a small team, we supported a large number of applications (12 developers with 100 applications) that covered every line of business in the company.  In short, we were [expletive deleted] good.

We weren't using unit testing.  And quite honestly, we didn't really feel like we were missing anything by not having it.  But companies reorganize (like they often do), and our team became part of a larger organization of five combined teams.  Some of these other teams did not have the same level of productivity that we had. Someone had the idea that if we all did unit testing, then our code would get instantly better.

So, I had a knee-jerk reaction (I had a lot of those in the past; I've mellowed a lot since then).  The problem is that unit testing does not make bad code into good code.  Unit testing was being proposed as a "silver bullet".  So, I fought against it -- not because unit testing is a bad idea, but because it was presented as a cure-all.

Warming Up
After I have a knee-jerk reaction, my next step is to research the topic to see if I can support my position.  And my position was not that unit testing was bad (I knew that unit testing was a good idea); my position was that unit testing does not instantly make bad code into good code.  So, I started reading.  One of the books I read was The Art of Unit Testing by Roy Osherove.  This is an interesting read, but the book is not designed to sell you on the topic of unit testing; it is designed to show you different techniques and assumes that you have already bought into the benefits of unit testing.

Not a Silver Bullet
I pulled passages out of the book that confirmed my position: that if you have developers who are writing bad code, then unit testing will not fix that.  Even worse, it is very easy to write bad unit tests (that pass) that give you the false impression that the code is working as intended.

But Good Practice
On a personal basis, I was looking into unit testing to see if it was a tool that I wanted to add to my tool box.  I had heard quite a few really smart developers talk about unit testing and Test Driven Development (TDD), so I knew that it was something that I wanted to explore further.

TDD is a topic that really intrigued me.  It sounded really good, but I was skeptical about how practical it was to follow TDD in a complex application -- especially one that is using a business object framework or application framework that supplies a lot of the plumbing code.

Actual Unit Testing
I've since moved on and have used unit testing on several projects.  Now that I am out of the environment that caused the knee-jerk reaction, I fully embrace unit testing as part of my development activities.  And I have to say that I see the benefits frequently.

Unit Tests have helped me to manage a code base with complex business rules.  I have several hundred tests that I run frequently.  As I refactor code (break up methods and classes; rearrange abstractions; inject new dependencies), I can make sure that I didn't alter the core functionality of my code.  A quick "Run Tests" shows that my refactoring did not break anything.  When I add new functionality, I can quickly make sure that I don't break any existing functionality.

And there are times when I do break existing functionality.  But when I do, I get immediate feedback; I'm not waiting for a tester to find a bug in a feature that I've already checked off.  Sometimes, the tests themselves are broken and need to be fixed (for example, a new dependency was introduced in the production code that the test code is not aware of).

I'm not quite at TDD yet, but I can feel myself getting very close.  There are a few times that I've been writing unit tests for a function that I just added.  As I'm writing out the tests, I go through several test cases and sometimes come across a scenario that I did not code for.  In that case, I'll go ahead and write the test (knowing that it will fail), and then go fix the code.  So, I've got little bits of TDD poking through my unit testing process.  But since I'm writing the code first, I do end up with some areas that are difficult to unit test.  I usually end up refactoring these areas into something more testable.  With a test-first approach, I might have gotten it "right" the first time.

Over the next couple weeks, I'll be diving into a personal project where I'm going to use TDD to see how it will work in the types of apps that I normally build.

One thing to note: my original position has not changed.  Unit Testing is a wonderful tool, and I believe that all developers should be unit testing at some level (hopefully, a level that covers the majority of the code).  But unit testing will not suddenly fix broken code nor will it fix a broken development process.

TDD
Now that I've seen the benefits of unit testing firsthand, I've become a big proponent of it.  And even though I didn't see the need for it several years back, I look back now and see how it could have been useful in those projects.  This would include everything from verifying that automated messages are sent out at the right times to ensuring that business rule parameters are applied properly to verifying that a "cleaning" procedure on user data was running properly.  With these types of tests in place, I could have made feature changes with greater confidence.

Advantages
When a developer is using TDD, he/she takes the Red-Green-Refactor approach.  There are plenty of books and articles that describe TDD, so I won't go into the details.  Here's the short version: The first step (Red) is to write a failing test based on a function that is required in the application.  The next step (Green) is to write just enough code for the test to pass.  The last step (Refactor) comes once you're a bit further into the process, but it is the time to re-arrange and/or abstract the code so that the pieces fit together.

The idea is that we only write enough code to meet the functionality of our application (and no more).  This gets us used to writing small units of code.  And when we start composing these small units of code into larger components, we need to maintain the testability (to make sure our tests keep working).  This encourages us to stay away from tight coupling and putting in abstraction layers as we need them (and not before).  In addition, we'll be more likely to write small classes that work in isolation.  And when we do need to compose the classes, we can more easily adhere to the S.O.L.I.D. principles.

Back to the Question
So this brings us back to the question we asked at the beginning: Should we modify our perfectly good code in order to make it easily testable?  And the answer is that if we write our tests first, then well-abstracted testable code will be the natural result.

I've done quite a bit of reading and other study of Unit Testing.  One of the things that I didn't like about some of the approaches is when someone "cracked open" a class in order to test it.  Because the unit they wanted to test was inaccessible (perhaps due to a "protected" access modifier), they wrote a test class that wrapped the code in order to make those members visible.  I never liked the idea of writing test classes that wrapped the production classes -- this means that you aren't really testing your production code.

However, if we take the approach of test-first development (with TDD or another methodology), then the classes we build will be inherently testable.  In addition, if a member needs to be injected or exposed for testing, it grows more organically with the corresponding tests.

Abstractions
And back to the last article about abstractions: if we approach our code from the test side, we will add abstractions naturally as we need them.  If we need to compose two objects, we can use interfaces to ensure loose-coupling and make it easier to mock dependencies in our tests.  If we find that we need to inject a method from another class, we can use delegates (and maybe the Strategy pattern) to keep the separation that we need to maintain our tests.

Wrap Up
Whole books have been written on unit testing (by folks with much more experience than I have).  The goal here was to describe my personal journey toward making unit tests a part of my regular coding activities.  I fought hard against it in one environment; this made me study hard so that I understood the domain; this led to a better understanding of the techniques and pitfalls involved.  There are three or four key areas that I have changed my thinking on over the years (one of which is the necessity of unit testing).  When I change my mind on a topic, it's usually due to a deep-dive investigation and much thought.  Unit testing was no different.

You may be working in a group that is not currently unit testing.  You may also think that you are doing okay without it.  You may even think that it will take more time to implement.  I've been there.  Start looking at the cost/benefit studies that have been done on unit testing.  The reality is that overall development time is reduced -- remember, development is not simply slapping together new code; it is also maintenance and bug-hunting.  I wish that I had done this much sooner; I know that my past code could have benefited from it.

My journey is not yet complete; it will continue.  And I expect that I will be making the transition to TDD for my own projects very soon. 

Maybe the other developers on your team don't see the benefits of unit testing, and maybe your manager sees it as an extension to the timeline.  It's easy to just go along with the group on these things.  But at some point, if we truly want to excel as developers, we need to stop being followers and start being leaders.

Happy Coding!