Archive for August, 2009

Essential Tool List Reloaded

Here’s an update to my Essential Tool list that I published last year. I highlighted all of the additions and changes in red.

I’m in JP’s Nothin’ But NET course this week, so I’m guessing that I’ll have many new ones to add shortly. However, I’ll probably also be so worn out from the class that I won’t be able to publish it for a while. The prep work alone almost did me in…:-)

As always, any new suggestions are welcome.

Development

Code Analysis

Development Lifecycle

Debugging

Utility

MISC

Essential WebSites

Popularity: 2% [?]

Frictionless Code Reviews

Having a second set of eyes on your code has multiple benefits.

Besides increasing the odds of catching bugs earlier in the process when they are less expensive to fix, code reviews tend to yield higher quality code that is more maintainable because you get feedback from someone who has not been immersed in the code and thus does not suffer from the blind spots that can be caused by working on something for too long.

It also leads to greater cross training in the code base (the hit by a bus factor) as well as knowledge sharing about coding practices in general. I’ve learned a lot of new techniques by simply reading code written by my co-workers.

Unfortunately, regular code reviews seem to be a rare practice in the industry because they are expensive in terms of time and difficult to manage due to egos. Most developers are very sensitive about the code they write and therefore it’s difficult to offer criticism without it being interpreted as a personal attack.

Even if reviews are built into a software shop’s SDLC, code reviews are often viewed as an ancillary activity and thus are usually first to be cut once a deadline looms (which is pretty much all the time in my experience).

Pair programming is one popular way to tackle this problem. It has all the benefits of code review, but bypasses the emotional issues by turning the review into a collaborative exercise. It also makes reviews more likely to happen because it becomes intertwined with the development process.

Although I clearly see the conceptual benefits of pair programming, I must admit that I am never very excited to participate in pair programming sessions on a regular basis. It’s probably just due to my introverted nature, but I feel most productive when I am in “the zone” and I can never seem to attain that state unless I am alone and in an environment with few distractions.

An alternative approach to pair programming that still makes the code review process inexpensive, stress free, and an integral part of the development process is to make it a required step of the development workflow and then adopt tools that make the process quick and painless to perform.

If code review happens all the time, then it ceases to be a stressful activity. If review is a required step before testing can occur (e.g. a step in the deployment script queries the issue tracking system and stops the deployment process if any unreviewed issues are returned), then it is no longer ancillary and avoidable. If tools help make it a frictionless process then it won’t be an undue burden that kills productivity.

I think we’ve achieved a relatively frictionless review process at StoreFinancial with the help of JIRA, Fisheye, TortoiseSVN, and a SVN hook.

First we ensure that a valid Jira key is entered into the comment field of the TortoiseSVN commit window with the help of a custom pre-commit hook that queries Jira to verify that the issue exists and is in an opened or resolved state before allowing the commit. I’ll describe how I did the hook in my next post and provide the source code.

If a developer forgets to enter the key or fat fingers the entry, then the code commit fails.

We originally purchased Fisheye to allow fast and sophisticated source control searching, but by far the biggest benefit we gained was the automatic association that happens between source code files and JIRA issues and the ability to view code directly in the browser. Within seconds of doing a commit, links to source control files will show up on a tab of the issue.

This allows the reviewer (in our case whoever finishes their developer tasks first) to grab an issue and quickly review it by simply clicking on the diff links of the Fisheye tab. The color coding scheme makes changes easy to see and the fact that it is within the browser minimizes the number of clicks required to do the reviews.

After reviewing all the files associated with the issue, the review can either mark the issue as reviewed or reopen it with comments and reassign it to the original developer to make the changes.

There are still parts of the code review process that I would like to streamline more.

In particular, I don’t like being a code formatting nazi so I’d like to move to shared ReSharper templates that automatically enforce formatting and syntax standards.

Otherwise, I’m quite pleased with the current state of our process and tools. With the addition of some simple tools it went from being expensive drudgery to being an relatively painless and valuable part of the development process.

Popularity: 2% [?]

LINQ to NHibernate: A Vast Improvement

In honor of the (relatively) new 1.0 status of LINQ to NHibernate, I’ve been spending the last few nights LINQifying some old NHibernate queries I’ve written and I must say that I’ve been very pleased.

There have traditionally been two ways of specifying NHibernate queries: HQL and the criteria query API.

Although I have an easier time deciphering HQL, which is basically a SQL-like string using classes instead of tables, I’ve tended to use the criteria API because it was somewhat strongly typed and thus easier to maintain with the help of refactoring tools like ReSharper.

Thanks to the new NHibernate LINQ provider, I can now work in a mode that is not only more type safe, but also much more readable.

Look at these before and after queries and judge for yourself:

Before (Criterion API)

   1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
   2: {
   3:     ICriteria criteria = Session.CreateCriteria(typeof(Call))
   4:         .CreateAlias("Customer", "Customer")
   5:         .Add(Restrictions.Gt("StartTime", beginDate))
   6:         .Add(
   7:            Restrictions.Or(
   8:                 Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
   9:                 )
  10:             )
  11:         .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
  12:         .AddOrder(Order.Desc("StartTime"))
  13:         .AddOrder(Order.Desc("Customer.Name"));
  14:
  15:     return criteria.List<Call>() as List<Call>;
  16: }

After (LINQ to NHibernate)

   1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
   2: {
   3:     var query = from call in Session.Linq<Call>()
   4:                     where call.StartTime > beginDate
   5:                         && (call.EndTime == null || call.EndTime < DateTime.Now )
   6:                         && call.Interpreter.Id == interpreterId
   7:                     orderby call.StartTime descending, call.Customer.Name
   8:                     select call;
   9:
  10:     return query.ToList();
  11: }

Apparently the NHibernate guys are still working on a full featured LINQ provider for a future version of NHibernate, but decided that the LINQ provider in the contrib project has been tested enough and used in enough production systems to promote it to RTM status.

The one thing I did notice when peeking at the SQL in Profiler is that the Linq provider produced an extra join that the regular Criteria API figured out wasn’t necessary because I was just referencing the foreign key column in the where clause. I’m guessing that minor differences like this will be addressed in the next version of the provider.

In the meantime, I’m still hooked enough to want to use this approach instead.

If you want to give LINQ to NHibernate a test run, just download and reference the one required dll here (make sure you’re using the same version of NHibernate).

If you’re still not comfortable with LINQ sytnax, here’s a simple example based MSDN tutorial to get you started.

Popularity: 16% [?]

Technical Book Sequels: A Case Study in Trying to Salvage a Second Edition

In a recent post, I raved about Jon Skeet’s book, C# in Depth. I thought it had all the yummy goodness of a six-shooter and then some.

Soon after I wrote the post, I discovered that Jon is currently working on a second edition to the book that will include new chapters devoted to C# 4.0 features. He wrote this post a few months ago that outlined the proposed content and solicited feedback from readers.

In particular, he seemed curious about what he could do to reach the widest possible audience with his second edition. The three target audiences he identified were 1) novice first time readers, 2) experienced first time readers who are already familiar with C# 2.0 and 3.0 features, and 3) developers who have already read the first edition.

At the risk of being sent a nasty LINQ-based virus by Mr. Jon Skeet, who is probably way too far into the writing process to be able to seriously consider feedback about the structure of his book, I thought I would weigh in on the topic. I have never considered purchasing a second edition of a tech book when I have already read and own a copy of the first edition, so the question of what would make me want to purchase a second edition intrigued me.

Here is what it would take for me to buy a second edition of C# in Depth:

  1. No Effort Is Made to Appeal to Novice Developers – The first edition distinguished itself by purposefully not targeting this audience as a way to stay focused. Any effort made to dumb down the book in hopes of expanding readership will likely only serve to alienate those of us who are already fans of the first edition and ultimately lead to a net loss in readers. Since the tech book market is already oversaturated with books targeting novice developers, it seems like it would be very difficult to capture any significant numbers from this group anyways.
  2. The Book is More of a Second Volume than a Second Edition – There are definitely some chapters that I wouldn’t mind rereading (iterators and expression trees come to mind), but otherwise it is not worth it for me to buy a book that is essentially a duplicate of one that I already have just because a few new chapters have been added to the end and some random revisions have been made. To be honest, it would probably take at least 60% new content before I would be willing to make the purchase. Some of the new content could be on novel uses of 2.0 and 3.0 language features that have emerged since the first edition was written, but mostly I want to read about C# 4.0.
  3. The Book Stays the Same Length – As I mentioned in my last post, I think that four hundred pages is probably a magic number for tech books when it comes to being appropriately focused. If the content is going to be 60% new and it is going to stay the same length, that means that some ruthless editing needs to take place. The goal of the book should definitely not be to be comprehensive, but rather to provide insight into particularly difficult and interesting topics that can’t be gleaned from a simple blog post. If someone wants to know about partial classes, automatic properties, or simplified initialization, they don’t need a book to find out about it. The Chapters on C# 2.0 should be probably be condensed to one chapter and the ones on C# 3.0 should probably be condensed to three chapters at the most.

Perhaps spending a few weeks every 2-3 years trimming material that is blatantly no longer relevant in order to produce a new edition might be worth the effort if they are just trying to capture a few straggling new readers, but anything beyond that seems like a hopeless exercise for the author and publisher who hope to sell any significant number of books.

It seems like a much better approach would be to consider this an essentially new book project (hence the volume 2 comment) and try to minimize the overlap in content between the two books.

Are my expectations unrealistic? Does anyone else see any true value in traditional second edition approach of adding a few new chapters and making a few minor revisions?

Since I liked the first book so much I will definitely follow Jon’s efforts and seriously consider his new edition.

However, based on my prior experience with second editions, Jon has an uphill battle ahead of him.

Popularity: 1% [?]

Bing Is Clearly Subpar

How does Bing expect to win the hearts and minds of geeks if it can’t even get this one little detail right?

Now observe how google handles this topic.

As you’ve probably guessed, clicking the recursion link in Google displays the exact same screen and it happens in every language.

I wonder how they wrote up the user story for this little easter egg

As a socially inept geek, I want to recursively click on the word recursion so that I can snicker while procrastinating on this user story.

Kudos to google. Even though you have grown to be just as monstrous of a corporate entity as Microsoft, you’ve obviously still managed to hold on to at least some of your geeky, non-corporate roots.

Also thanks to my co-worker, Marc Shiker, for pointing this gem out to me.

Popularity: 9% [?]

On C# in Depth and the State of Old School Technical Publishing

I recently downsized my technical library and got rid of about 20 brick-sized technical books.

Some of the books covered obsolete technologies, but I got rid of most of them simply because I’d rather access the information that they covered through a search engine on an as needed basis rather than by slogging through a 1000 pages of obscure corner cases up front that I probably will never need or else will forget by the time I actually do need to know it.

If I no longer consider the traditional technical books that I spent obscene amounts of money on as little as 4-5 years ago as even being worthy of collecting dust in my basement, just imagine how reluctant I am to actually spend money on those types of books today and in the foreseeable future.

As far as I can tell, I am not the only one who feels this way. Indeed, I often feel like an out-of-touch old-timer every time I’m greeted with a long silence after asking potential candidates on phone interviews which technical books they have read recently.

Does that mean that the end is near for technical book publishers?

Although it is certainly possible that publishing companies will eventually go the way of many developer magazines like Dr. Dobs, I tend to take the more optimistic viewpoint that the technical publishing landscape will simply shift to more fertile grounds.

Instead of continuing to churn out books that are little more than glorified reference materials, I believe that savvy publishers will start seeking out authors who are able to tell a story and convey a deeper understanding of the underlying principals and technologies in a such a way that the knowledge will not be rendered obsolete as soon the next version comes out, the API changes, or an additional layer of abstraction is added.

I think Jon Skeet’s book, C# in Depth: What you need to master C# 2 and 3, is a perfect example of this new breed of book that will thrive despite the ubiquity of search engines, twitter streams, blog rants, and exhaustive online documentation..

Here are some fundamental aspects of the book that Jon got right:

  1. Narrow Scope – I can’t say how pleased I was to NOT have to contend with an additional 800 pages of basic information on conditional statements and inheritance just to get to the part of the book that I most cared about, the 2.0 and 3.0 features of the language. Just like a large LOC (Lines of Code) count in methods and classes are code smells that indicate a need for refactoring, an excessive number of pages in a book is a clear indication that the book is trying to do too much. I simply won’t consider buying a book that is over 400 pages anymore and it’s not because I have a short attention span (although I do). If the author doesn’t even know what the essence of the book is, then what hope do I have of gleaning it?
  2. Cohesive Story – Reading a typical Wrox reference style book often feels like reading a dictionary or encyclopedia because the content is organized along more or less meaningless categories. By contrast, this book is organized along several story-like themes. First Jon  chose to order the book chronologically and take pains to describe the perceived shortcomings of earlier versions of the language, thus giving a sense for how and why the language evolved. For example, Generics were added in 2.0 to address the performance implications (boxing and unboxing) and type safety issues of using Object as a universal type for methods or collections that dealt with multiple different types. The book also provides a nice cognitive framework for understanding the hodgepodge of 3.0 features by explaining how they are necessary in laying the groundwork for LINQ. Now when I look at a LINQ query, what I really see is a combination of extension methods, lambda expressions, and anonymous types.
  3. Why Over How– When I first looked at some of the 3.0 syntax, I had trouble even recognizing it as C#. The foreign feeling of the syntax eventually disappeared after repeated use, but the underlying sense of it being some inexplicable magic remained. This book helps dispel that feeling by explaining the underlying mechanics for all the syntactic sugar. For example, Jon shows output from Reflector to demonstrate how the C# compiler translates LINQ queries into the method calls against the new IList extension methods or how it turns anonymous types and anonymous delegates into concrete types with compiler generated names. It’s amazing how much more comfortable I suddenly felt with the syntax once I had a better understanding of what was actually happening behind the scenes.
  4. Code Samples As Supporting Evidence – If the thesis is that new syntax represents a fundamental improvement in the language, then there is no proof more persuasive than code. Jon does this particularly effectively by taking the time to implement his samples first in 1.1, then in 2.0, and finally in 3.5 so you can easily see how code grows progressively more concise, readable, and expressive with each iteration. This was particularly helpful in the case of delegates, anonymous methods, and lamdas since they all essentially do the same thing but are expressed in vastly different ways. I was never fully sold on lamdas until I saw how many more lines of code was required to do the exact same thing using good old fashioned delegates.

I’m not saying that the book was a perfect piece of literature or that you will walk away from it an instant C# guru. There are definitely some parts on iterators (the yield keyword) and expression trees that I only partially groked (although I think that has more to do with my own limited processing power than any shortcomings in the book).

However, I would definitely highly recommend this book to any .NET developer. In fact, I would classify it as a must-read for any C# developer.

I would also strongly urge any book authors and publishers out there to take some serious notes on the general approach of this book. The rules of the game have changed. I would rather <insert reader comment here> than spend one more dime on another 1000 page dead tree reference.

** Off Topic: Looking for a job in the Kansas City area? Come work with us at StoreFinancial.

Popularity: 9% [?]