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: Clean Code

The most recent book I finished reading is Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin -- a.k.a. Uncle Bob (Amazon link).  Note that this is not be confused with The Clean Coder (also by Robert C. Martin) which I talked about in a previous article.

To differentiate the books, Clean Code is all about how to make sure that your output (the code) is well written and intentional (not simply slapped together).  The Clean Coder is all about how to make sure that you (the coder) are professional and intentional.

Practical Advice
Clean Code is about identifying "code smells" -- those things that aren't quite right about code.  Well-seasoned developers are (generally) adapted to identifying the smells.  We've come across code smells in previous articles (including here and here) and also in Robert C. Martin's book Agile Principles, Patterns, and Practices in C#.  This book (Clean Code) has an entire chapter devoted to common code smells (and also an appendix that cross-references the code smells throughout the other chapters).

Just by looking through the table of contents, we can glean a lot of useful tips.  (I'm not quite sure what to call these: "rules" sounds too strong, and "tips" does not sound strong enough.)  Here are just a few:

Chapter 2: Meaningful Names
  • Use Intention-Revealing Names
  • Use Pronounceable Names
  • Don't Be Cute
  • Pick One Word per Concept
Chapter 3: Functions
  • Do One Thing
  • Have No Side Effects
  • Don't Repeat Yourself
Chapter 4: Comments
  • Comments Do Not Make Up for Bad Code
  • Explain Yourself in Code
And these are just a few of the chapters.  Each section doesn't just give the advice, it talks about the reasoning behind it.  This gives us a motivation to start to incorporate it into our code.

There are some things that you may not agree with -- and that's okay.  What's important is that we are thinking about why we are making a decision one way or another.  A lot of times, we may find that we don't have a good reason for doing things the way we do (other than "that's the way I've always done it" or "that's the way I was taught").

At the same time, there will probably be many things that you agree with but don't do.  As I was reading, I constantly found myself thinking about my current project and how I was or was not applying these tips.

An Iterative Process
One of my biggest take-aways from Clean Code is that clean code is not something that comes out in the first iteration.  We need to revisit our code and refactor as necessary.  Often it takes several iterations to get a piece of code right.

Several of the chapters show the process of refactoring actual code.  This shows the steps and thought process behind the decisions as they are made.  In addition, it shows that sometimes we may end up reversing a previous refactoring as we go further down the path.

This iterative process also means that we are not optimizing or abstracting too early in the process.  When we first write a block of code, we may not know that we need to use it in other parts of the application.  But if we find ourselves doing a copy/paste, we should pull that code out into a separate method or class rather than duplicating it.

The iterative process also applies to the complexity of a method.  As an example, in my current project, we have initialization code for each module.  These often start out small, with just four or five lines of code.  But as more functionality gets fleshed out, the initialization routine may grow in complexity -- often with if/else or switch statements.  The method doesn't end up very long (just about 30 lines or so); however, by thinking is smaller chunks, we can split that 30 lines into 3 or 4 smaller, more focused methods.  Then our initialization routine just has 3 or 4 lines of code (that call those separate methods), and if we name the methods meaningfully, then it is very clear what the initialization method is trying to accomplish.  If we need details, then we can always drill down into the specific methods.

Unit Testing / TDD
Unit Testing and TDD (Test Driven Development) are extremely important when going through this iterative process.  If we have good unit tests in place, then we can be confident that we did not break the functionality when we move or refactor code.  If we do not have unit tests in place, then we cannot be sure.

I have experienced this in my own code.  Where I have good unit test coverage, I can make updates confidently.  And if something breaks (either in the code or the unit test), then I know that something is wrong.  Sometimes I need to update my code, and sometimes I need to update the unit test to reflect different functionality.  But if we are simply refactoring (with no functionality updates), then our unit tests should continue to pass without modification.

Why Do We Care?
In most situations, we will not maintain the code that we write forever.  Someone else will need to take it over at some point.  At the same time, we have had to take over someone else's code.  Think about your own experience.  Sometimes it is good -- the code is clear and you can jump right in to making changes.  Sometimes it is bad -- and you have to untangle the intention before you can make any modifications to the code.

I try to live with this approach: Always assume that the person who has to maintain your code is a homicidal maniac who knows where you live. This is especially important in my current role as a contract programmer.  I know that after I leave this project, someone else will have to maintain (and enhance) the code that I write.  My goal is to make sure that the people who come behind me can do that with as little difficulty as possible.  I don't want to be "that contractor who wrote the code no one can understand."  I want to be the guy who built a good foundation for the future of the application.

Wrap Up
Clean Code has made me think a lot about the approach I take to my code.  The good news is that I found that I recognize most of the code smells enumerated in the book.  But there is always room for improvement, and the areas that I did not previously recognize now jump out at me.

Being a developer is constant learning.  Many times we are learning new technologies.  But we also have to stop and re-evaluate coding style and best practices.  There are many smart people who have gone before us.  We can benefit from their experience and build better, more maintainable projects.

Happy Coding!

Book Review: The Clean Coder

About a month ago, I finished reading The Clean Coder: A Code of Conduct for Professional Programmers by Robert C. Martin -- a.k.a. Uncle Bob (Amazon link).  The key word here is "professional".  The book focuses on the qualities that make someone a true professional and the way that developers often sabotage themselves with the unprofessional actions that are (sadly) expected our industry.

It's a short book (about 200 pages), and I definitely recommend it to anyone who is in the development field.  I didn't really come here to review the book but to put down some of my thoughts on the subject.

Development Teams as Suppliers
Over the last few months, I've been thinking more about the state of development and development teams in most companies.  I've talked to colleagues who have had really bad experiences at their company and to colleagues who have had really good experiences.  What distinguishes the two?  And is there any way to influence the company you work at to move in a better direction?

Many times, the software development division is seen as completely separate from the rest of the company. The division is there to do the bidding of the business.  What I would like to see is that the software division is seen just like any other department in the company.  Here's an example of someone who was looking for this same thing:

At a previous company, I had an I.T. Vice President who had a goal: he wanted to be asked about the color of the carpet in the new building.  This is just a trivial example of the type of question he wanted to be asked, but that's sort of the point.  The company would come to him whenever they had issues that required a technical solution, but that was it.  He noticed that in executive meetings where they would discuss the "color of the carpet", input would be requested from HR and Marketing and Finance even though the question didn't have anything to do with those specific divisions.

These other divisions were seen as a true part of the company while I.T. was seen as a supplier.  His goal was to get I.T. into the same position as the other divisions of the company.  Sadly, I don't believe that he ever achieved that goal, but I have a better understanding now of why he was pursuing it.

Moving from a Supplier to a Partner
So, the question is: how do development teams make the transition from supplier to partner?  I wish I had a good answer to this.  I've worked in several different environments.  In some, the developers were truly partnered with the business.  As an individual developer, I spent time with the users out in the business area.  I would go and watch them work for a day to see what types of issues they had in their current environment. The goal was to understand the difference between what they think they need to make things more efficient and what they actually need to make things efficient.

Part of the reason this is necessary is that the business users generally do not have a good idea of what is possible.  And even if they do have a good sense of what is possible, they may not be able to tell the difference between what is easy and what is hard.  That's where we really need to step up and fill that role.

As an example: on a particular application, I was building a data verification screen.  Because I had spent time with the users, I knew their workflow and how they kept track of their various activities.  So, even though it was not requested, I suggested that a "print" button be added to a particular screen.  This turned out to be a huge win from the user's point of view.

I was able to make this suggestion due to a few reasons: First, I knew what the users needed -- this was based on me watching and understanding their workflow.  Next, I knew it was an "easy win".  I had recently implemented a similar print functionality on another application, so this was literally 5 minutes worth of work.

These are the types of situations that I live for -- being able to go above and beyond the users expectation while still staying within project scope.

Project Scope and Estimation
Project scope is always a difficult subject to deal with.  The business areas are generally making additional requests throughout the development process.  This is how we ended up with Agile and other methodologies that are focused on constantly re-evaluating the scope and implementation periods for certain features.  Delivering quickly and delivering often really sounds like a good idea, but the reality of most of the projects that I have worked on is that there was a certain "critical mass" that had to be reached before the software could be released.  Once this "critical mass" is hit, then other features can be added.  But often, the initial release takes a while to get out.

Estimation is a big topic in The Clean Coder (as it should be).  That's because we, as developers, are historically unrealistic with our estimates.  We generally fall into 2 groups: those who grossly underestimate, and those who grossly overestimate.

Under-estimation can be due to developers simply not thinking it through.  Or because the developer doesn't really understand his skillset.  Or because the developer likes to be seen as the "hero" -- someone who can turn around things inordinately quickly.

Over-estimation can be due to developers not having enough information.  Or because the work does not excite the developer.  Or because of ineffective time management.

Perfect estimation is a near impossibility in our industry.  After all, what other business is asked to come up with concrete time frames for things that have never been done before?  And this varies greatly depending on whether we are doing coarse-grained or fine-grained estimates.  With coarse-grained estimates, we probably have not done enough analysis to really know how long things will take.  With fine-grained estimates, we could end up with many small errors that get compounded when all of the estimates are added together.

I had one extremely good manager who understood her developers.  She knew that when John gave her an estimate, she should multiply it by 2.  When Janice gave an estimate, it was about 50% high.  And when Kevin gave an estimate, she should divide it by 3.  (Note: all names have been changed to protect the innocent.)  Because of this, the manager made our team look good to the business.  We hit our time frames pretty consistently (and much more consistently than other teams in the division).

Learning to Say No
One interesting topic in The Clean Coder involves learning to say no.  By our nature, we want to make people happy.  That's why we build software -- to meet someone else's needs in a way that we can take pride in.

Because of this, if we are asked if we can make something happen more quickly, we have a tendency to say yes.  This may be because we are engrossed in a feature that we want to get completed (and so we are probably going to spend extra time anyway), or just because we want to be seen as a "team player".

Uncle Bob argues that if we are making good (realistic) estimates, then we can't complete the job any faster. If it is possible to get a job done in 4 days instead of 5, then we were off by 25% in our estimate.  If we can only get the job done by working that 5th day after hours (an extra 2 hours a day for 4 days), then that means our estimate was correct; however, we really need to worry about the perception.

Working that extra 2 hours a day for 4 days is probably not going to cause any problems.  But if we make this concession in one case, then we will be asked to do it again -- probably repeatedly.  Because of this, we need to not simply say yes, but to make sure that the people we are promising understand the extra effort that will be required.

In the example above (4 days vs. 5 days), if the manager says that they really need something done on Thursday (due to a hard deadline somewhere), then you could say that you are willing to put in extra hours for 4 days in order to hit the date, but that you will not be coming in on that 5th day.

This may sound a little extreme, but I have had the experience of working way too many hours which had a detrimental effect on me.  We were working on a quarterly release for a product.  I had been tracking it for several months, and (from what I could tell) we were going to make our release date.  When it came to "crunch time" there was still a lot of work to do, so I was working evenings and weekends to make sure that my part of the process was complete.  Due to some things out of my control, the release date was moved another two weeks.  And then another 4 weeks.  And then another 2 weeks.

The upshot was that I ended up in "crunch time" for 4 months.  This was a terrible situation to be in.  Whenever I saw my work laptop, I was thinking about all of the things that I needed to do.  I was working weekends to try to get things out on Monday morning.  I dreaded getting up each morning because all I could think about was how much unfinished work I had.  I let myself burn out.

Notice that I said that "I let myself".  I was in full control of the situation.  At any time, I could have taken a day off or not worked late into the evening.  But I wasn't letting myself do that.  I was too wrapped up in the work to have a good perspective.

Remember: it's just software.  If you are late with your work, no one is going to die (with very rare exceptions).  Part of being a "team player" is understanding that you cannot be an effective player if you are not at the top of your game.  And it's impossible to be at the top of your game if you are constantly running non-stop.  Take time to breathe.  Take time to relax.  Take time to refresh yourself.

And remember that it's okay to say no.

Wrap Up
The Clean Coder contains many nuggets of wisdom.  Unfortunately, when you read the book, you'll probably say, "Well, that's obvious."  Most of the things are -- they cover how to be a responsible professional.  But for some reason, this is missing in our industry (or at least perceived to be missing).  By focusing on how we can better ourselves and behave as professionals, we can have an impact on our own company and spread this thinking further in the industry.

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.  (And lest you think that I made this up myself, Robert C. Martin also talks about only adding abstractions when you need them in Agile Principles, Patterns, and Practices in C#.)

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.

About that same time is when I first read Agile Principles, Patterns, and Practices in C# by Robert C. Martin and Micah Martin (mentioned last time).  In one especially interesting chapter, Martin uses TDD to walk through the creation of an application to score bowling (a task with quite a few different "business rules").  This gave me a really good feel for the process of TDD and the tight, cyclical nature.  It made me want to explore further.

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.

I'll mention 2 more Robert C. Martin books Clean Code and The Clean Coder.  The first deals with writing good code (including how to identify "code smells"); the second deals with how to be a professional developer (a real professional, not just someone who does development for money).  Both of these books espouse TDD as "the way to program" -- and they do this in a way that is very hard to refute.

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; start reading folks like Robert C. Martin about the real world reasons it is a good idea.  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!

Saturday, October 20, 2012

Abstraction: The Goldilocks Principle

Abstractions are an important part of object-oriented programming.  One of the primary principles is to program to an abstraction rather than a concrete type.  But that leads to a question: What is the right level of abstraction for our applications?  If we have too much abstraction, then our applications can become difficult to understand and maintain.  If we have too little abstraction, then our applications can become difficult to understand and maintain.  This means that there is some "sweet spot" right in the middle.  We'll call this the Goldilocks level of abstraction: "Just Right."

So, what is the right level?  Unfortunately, there are no hard-and-fast rules that are appropriate for all development scenarios.  Like so many other decisions that we have to make in software development, the correct answer is "it depends."  No one really likes this answer (especially when you're just getting started and are looking for guidance), but it's the reality of our field.

Here are a few steps that we can use to get started.

Step 1: Know Your Tools
The first step to figuring out what abstractions to use is to understand what types of abstractions are available.  This is what I focus on in my technical presentations.  I speak about delegates, design patterns, interfaces, generics, and dependency injection (among other things).  You can get information on these from my website: http://www.jeremybytes.com/Demos.aspx.  The goal of these presentations is to provide an overview of the technologies and how they are used.  This includes examples such as how to use delegates to implement the Strategy pattern or how to use interfaces with the Repository and Decorator patterns.

We need to understand our tools before we can use them.  I try to show these technologies in such a way that if we run into them in someone else's code, they don't just look like magic incantations.  If we can start looking at other people's code, we can get a better feel for how these tools are used in the real world.

A while back, I wrote an article about this: Design Patterns: Understand Your Tools.  Although that pertains specifically to design patterns, the principle extends to all of the tools we use.  We need to know the benefits and limitations to everything in our toolbox.  Only then can we make an informed choice.

I remember seeing a woodworking show on television where the host used only a router (a carpentry router, not a network router).  He showed interesting and unintended uses for the router as he used it as a cutting tool and a shaping tool and a sanding tool.  He pushed the tool to its limits.  But at the same time, he was limiting himself.  He could use it as a cutting tool, but not as effectively as a band saw or a jigsaw or a table saw.  I understand why this may be appealing: power tools are expensive.  But in the software world, many of the "tools" that we use are simply ideas (such as design patterns or delegates or interfaces).  There isn't a monetary investment required, but we do need to make a time investment to learn them.

Step 2: Know Your Environment
The next step is to understand your environment.  Whether we are working for a company writing business applications, doing custom builds for customers, or writing shrink-wrap software, this means that we need to understand our users and the system requirements.  We need to know what things are likely to change and which are not.

As an example, I worked for many years building line-of-business applications for a company that used Microsoft SQL Server.  At that company, we always used SQL Server.  Out of the 20 or so applications that I worked on, the data store was SQL Server.  Because of this, we did not spend time abstracting the data access code so that it could easily use a different data store.  Note: we did have proper layering and isolation of the data access code (meaning, all of our database calls were isolated to specific data access methods in a specific layer of the application).

On the other hand, I worked on several applications that used business rules for processing data.  These rules were volatile and would change frequently.  Because of this, we created rule interfaces that made it very easy to plug-in new rule types.

I should mention that these applications could have benefited from abstraction of the database layer to facilitate unit testing.  We were not doing unit testing.  In my next article, I will talk more about unit testing (and my particular history with it), and why it really is something we should all be doing.

Step 3: Learn the Smells
Robert C. Martin (a.k.a. "Uncle Bob") talks about "code smells" in Agile Principles, Patterns, and Practices in C# (a book that I recommend).  I have heard other programmers talk of "code smells" as well.  This basically comes with experience.  As a developer, you look at a bit of code and something doesn't "smell" right -- it just feels off. Sometimes you can't put your finger on something specific; there's just something that makes you uncomfortable.

There are a couple of ways to learn code smells.  The preferred way is through mentorship.  Find a developer with more experience than you and learn from him/her.  As a young developer, I had access to some really smart people on my development team.  And by listening to them, I saved myself a lot of pain over the years.  If you can learn from someone else, then be sure to take advantage of it.

The less preferred (but very effective) way of learning code smells is through trial and error.  I had plenty of this as a young developer as well.  I took approaches to applications that I later regretted.  And in that environment, I got to live with that regret -- whenever we released a piece of software, we also became primary support for that software.  This is a great way to encourage developers to produce highly stable code that is really "done" before release.  While these applications were fully functional from a user standpoint, they were more difficult to maintain and add new features than I would have liked.  But that's another reality of software development: constant learning.  If we don't look at code that we wrote six months ago and say "What was I thinking?", then we probably haven't learned anything in the meantime.

Step 4: Abstract as You Need It
I've been burned by poorly designed applications in the past -- abstractions that added complexity to the application without very much (if any) benefit.  As a result, my initial reaction is to lean toward low-abstraction as an initial state.  Because of this, I was very happy to see Robert C. Martin espouse the approach of waiting to add an abstraction until you actually need it (in the same Agile Principles book mentioned above).  This is an extremely good approach if you don't (yet) know the environment or what things are likely to change.

As an example, let's go back to database abstractions.  It turns out that while working at the company that used SQL Server, I had an application that needed to convert from SQL Server to Oracle.  The Oracle database was part of a third-party vendor product.  For this application, I added a fully-abstracted repository that was able to talk to either SQL Server or the Oracle database.  But I just did this for one application when I needed it.

Too Much Abstraction
As mentioned above, too much abstraction can make an application difficult to understand and maintain.  I encountered an application that had a very high level of abstraction.  There were new objects at each layer (even if the object had exactly the same properties as one in another layer).  The result of this abstraction meant that if someone wanted to add a new field to the UI (and have it stored in the database), the developer would need to modify 17 different code files.  In addition, much of the application was wired-up at runtime (rather than compile time), meaning that if you missed a change to a file, you didn't find out about it until you got a runtime error.  And since the files were extremely decoupled, it was very difficult to hook up the debugger to the appropriate assemblies.

Too Little Abstraction
At the other end of the spectrum, too little abstraction can make an application difficult to understand and maintain.  Another application that I encountered had 2600 lines of code in a single method.  It was almost impossible to follow the logic (lots of nested if/else conditions in big blocks of code).  And figuring out the proper place to make a change was nearly impossible.

"Just Right" Abstraction
My biggest concern as a developer is finding the right balance -- the Goldilocks Principle: not too much, not too little, but "just right".  I've been programming professionally for 12 years now, so I've had the benefit of seeing some really good code and some really bad code (as well as writing some really good code and some really bad code).

Depending on what kind of development work we do, we can end up spending a lot of time supporting and maintaining someone else's code.  When I'm writing code, I try to think of the person who will be coming after me.  And I ask myself a few key questions.  Will this abstraction make sense to someone else?  Will this abstraction make the code easier or harder to maintain?  How does this fit in with the approach used in the rest of this application?  If you are working in a team environment, don't be afraid to grab another developer and talk through a couple of different options.  Having another perspective can make the decision a lot easier.

The best piece of advice I've heard that helps me write maintainable code: Always assume that the person who has to maintain your code is a homicidal maniac who knows where you live.

One other area that will impact how much abstraction you add to your code is unit testing.  Abstraction often helps us isolate code so that we can make more practical tests.  I'll be putting down my experiences and thoughts regarding unit testing in the next article.  Until then...

Happy Coding!

Thursday, October 11, 2012

Session Spotlight - Dependency Injection: A Practical Introduction

I'll be speaking at SoCal Code Camp (Los Angeles) on October 13 & 14.  If you're not signed up yet, head over to the website and let them know that you're coming: http://www.socalcodecamp.com/.

Also, I've got a brand new session: Dependency Injection: A Practical Introduction

How Do We Get Started With Dependency Injection?
One of the big problems with getting started with Dependency Injection (DI) is that there are a lot of different opinions on exactly what DI is and the best ways to use it.  At its core, DI is just a set of patterns for adding good abstraction to our code.  The objects we create should be focused on doing one thing and doing it well.  If there is functionality that is not core to the the object, then we "outsource" it to another class.  This external class is a dependency (our primary object depends on this other class to provide a functional whole in our application).

Dependency Injection gives us a way to keep these external dependencies separate from our objects.  Rather than the object being responsible for creating/managing the dependency, we "inject" it from the outside.  This makes sure that our classes are loosely coupled which gives us good maintainability, extensibility, and testability.

In this session, I combine my personal experience using DI with the excellent information provided by Mark Seemann in Dependency Injection in .NET (I posted a review on this book a few weeks back).

DI is an enormous topic. I have picked out a few key areas (like examining tight-coupling and loose-coupling) and design patterns that will give us a good starting point for the world of DI.  (As a side note, the sample code also gives a quick example of using the Model-View-ViewModel (MVVM) design pattern.)

If you can't make it out to the SoCal Code Camp, you have another chance to see this session at the Desert Code Camp (in the Phoenix, AZ area) in November.  And as always, the code samples and walkthrough are posted on my website.

Hope to see you at an upcoming event.

Happy Coding!

Sunday, September 30, 2012

Session Spotlight - IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

I'll be speaking at So Cal Code Camp (Los Angeles) on October 13 & 14. If you're not signed up yet, head over to the website to let them know you're coming: http://www.socalcodecamp.com.

Back again: IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces.

Abstraction Through Interfaces
When people talk about interfaces, they often refer to the User Interface -- the screens and controls that allow the user to interact with the application.  But "interface" also refers to a very powerful abstraction that lets us add extensibility and loose coupling to our code.

My first encounter with interfaces was in Delphi (Object Pascal) as a junior developer.  I understood what they were from a technical standpoint, but I didn't understand why I would want to use them.  We went to the Borland conference every year; and as a new developer, I took the opportunity to absorb as much information as I could, even if I didn't understand most of it (this is also a great way to use Code Camp -- to experience technologies you haven't taken the time to look into yet).  I was very excited because there was a session in Interfaces at the conference.

"Great," I thought, "I'll go and get some practical examples of how to use interfaces and find out why I would want to use them."  So, I get to the session, sit down, and grab my notepad -- ready to spend the next hour getting a practical introduction.

The speaker gets up and starts the presentation.  "So, let's say that we have an Foo class.  And we also have an IBar interface."

"Noooooooooooooooo!" I screamed (well, screamed inwardly anyway).  "I need practical examples.  You can't use Foo / Bar / Baz examples."  But that's the way it was, and I didn't get anything new out of the session.  (I also talked to some of my senior developer coworkers who attended, and they didn't get anything out of it either.)

It was several more years before I had a good grounding in object oriented design and the hows and whys of abstraction.  The goal of "IEnumerable, ISaveable, IDontGetIt" is to give you a jump-start to understanding interfaces.  We use real examples from the .NET framework and from actual application abstractions that I have coded in my professional career.

In addition to the So Cal Code Camp on Oct 13/14, I'll also be presenting this session at the Desert Code Camp (Phoenix) on Nov 17.  And if you're quick, you can also see me present this information this week at a couple of user groups.

Hope to see you at an upcoming event.

Happy Coding!

Tuesday, September 25, 2012

Upcoming Speaking Engagements - October 2012

October is shaping up to be a busy month.  I have several speaking engagements which will be a lot of fun.  Code Camps and User Groups are a great place to get out and talk to other developers -- find out what works and what doesn't work, and learn a lot of great new techniques.

Tuesday, October 2, 2012
LA C# User Group - Manhattan Beach, CA
Topic: IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

Wednesday, October 3, 2012
So Cal .NET - Buena Park, CA
Topic: IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

Saturday / Sunday, October 6 / 7, 2012
Silicon Valley Code Camp - Los Altos Hills, CA
Topics:
Get Func<>-y: Delegates in .NET
Learn to Love Lambdas

Saturday / Sunday, October 13 / 14, 2012
SoCal Code Camp - Los Angeles, CA
Topics:
Dependency Injection: A Practical Introduction
IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces
Learn to Love Lambdas
T, Earl Grey, Hot: Generics in .NET

Stop by if you can; the more, the merrier.

Happy Coding!

Tuesday, September 18, 2012

Session Spotlight - Learn to Love Lambdas

I'll be speaking at SoCal Code Camp (Los Angeles) on October 13 & 14. If you're not signed up yet, head over to the website and let them know that you're coming: http://www.socalcodecamp.com/.

Back by popular demand: Learn to Love Lambdas

Lambda Expressions
Lambda expressions are a very powerful tool that can add elegance to our code.  The problem is that they look like a secret code the first time you see them.  You've probably come across something that looks like this:


It looks daunting, but it's fairly easy to learn.  The lambda expression that we have here is just an anonymous delegate.  If we were to use a more verbose syntax, we get something like this:


We are probably a bit more comfortable with this syntax.  Here, we can tell that we're hooking up some sort of event handler, and it has standard event handler arguments: object and some type of EventArgs.  Inside the method body, we are assigning the Result property of the EventArgs to display in a list box.

This anonymous delegate is equivalent to the lambda expression above.  To create the lambda expression, we just replace the "delegate" keyword (before the parameters) with the "goes to" operator (=>) after the parameters.  The parameter types are optional, so we can get rid of those.  Also, since the method body only has one statement, we can remove the curly braces.  This leaves us with a compact and readable syntax.

Delegates abound in the .NET framework (and in add-on frameworks like the Prism library).  Whenever we have LINQ extension methods, event handlers, callbacks, or tasks, we can use lambda expressions to add compact blocks of code right where they are most useful.  And in some instances (like when working with the Prism variants of RaisePropertyChanged) we can make our code more conducive to refactoring by replacing strings with compiler-checked pieces of code.

Once you get used to lambda expressions, they are extremely readable.  In this session, we'll learn the lambda syntax, use lambdas for asynchronous callbacks, see a really cool feature that makes code safer, and see how lambdas were designed to be used extensively in LINQ.  If you'd like to Learn to Love Lambdas, be sure to stop by my session at a code camp near you.

In addition to the SoCal Code Camp on Oct 13/14, I'll also be presenting this session at the Silicon Valley Code Camp on Oct 6/7 (this session is scheduled for 2:45 p.m. Sunday afternoon -- last session of the day).

Also be sure to check out the walkthrough and code samples here: Jeremy Bytes.

Hope to see you at an upcoming event.

Happy Coding!

Wednesday, September 12, 2012

Session Spotlight - T, Earl Grey, Hot: Generics in .NET

I'll be speaking at SoCal Code Camp (Los Angeles) on October 13 & 14.  If you're not signed up yet, head over to the website and let them know that you're coming: http://www.socalcodecamp.com/.

Also, I've got a brand new session: T, Earl Grey, Hot: Generics in .NET

Generics in .NET
Most C# developers have worked with generics to a certain extent (often by using classes from the base class library like List<T>).  But we don't have to stop by merely consuming classes with generics; we can also create our own classes and methods that take advantage of this great framework feature.

We got generics way back in .NET 2.0, and they really were transformational at the time (now we're hopefully used to seeing them).  Using generics, we can add type-safety to our code while still maintaining extensibility.  By making our code type-safe, we are more likely to catch errors at compile time and also avoid strange behavior that might come from casting objects to different types.  Our code also becomes more extensible -- it can work with types that it may not have been originally intended to work with.

Generics also offer us some performance enhancements (which, granted, seem fairly minor when talking about the processing resources of modern devices) by reducing casting calls and boxing/unboxing of value types.

In the session "T, Earl Grey, Hot: Generics in .NET", we'll take a look at the basic features of generics (by comparing non-generic and generic versions of classes from the base class library), see how we can incorporate generics into our own classes and methods in a practical way, and explore the various options to take full advantage of generics in our code (like "default" and generic constraints).

If you can't make it out to the SoCal Code Camp, you have another chance to see this session at the Desert Code Camp (in the Phoenix, AZ area) in November.

Hope to see you at an upcoming event.

Happy Coding!