Less Is More

by October 25, 2008 06:37 PM

As Bob Koss (on Object Mentor) puts it in Size Matters:

classes are just too damn big and methods are just too damn long

I couldn't agree more! I was recently tasked with adding functionality to an existing website at work. The point in the process where I was to add functionality was in the middle of this nasty page where there were multiple panels that were just hidden or shown depending on where you were in this mini process flow. The aspx was over 500 lines long and the code behind over 1,000! I cried inwardly when I realized the desired functionality was right in the middle of this mess. I did some soul searching and analysis and determined that splitting this mess into multiple pages wouldn't take much longer than figuring out how to add to the existing page without breaking anything.

As I was breaking the page into multiple pages, what Jeff Attwood said in Size Is The Enemy really hit home.

Lines of code are, and always have been, the enemy. More lines of code means more to read, more to understand, more to troubleshoot, more to debug.

The code was extremely difficult to decipher. Not only was so much functionality packed into one page, each method was crazy long and overly complex. At the end of this post is one such method along with how I refactored it after moving it into the new page I created for that piece of the puzzle. I hope you'll agree that the refactored version is much easier to read and understand quickly. And that's the key - to add to a code base without breaking it, you have to be able to understand it and I want to do that quickly. When an analyst or a user says "it's only one new button" or some such nonsense, I want them to be right! Nothing frustrates me more than when a task that seems like it should only take a day or two actually takes a week or two and it's because of the unnecessary complexity left by the yahoo coder before you.

A couple of things about the code below. First, don't bother trying to grok the pre-refactored code - it's just there to note. I assure you I tested and the shorter version captures exactly the same thing as the the longer. Second, one might be tempted to say the shorter version is only better if you understand lambdas and LINQ. To that I say, true. But consider this. A new developer coming on who doesn't know them will only have to learn them once and will then be capably of understanding all the rest at first glance. Doing it the old-school looping, if-else, and temp variables way means the poor developer will have to decipher the craziness over and over again. And each and every time is a lot of unnecessary time added to that simple button request.

So, to summarize: Less Is More!! Make every attempt to accomplish your programming tasks in as few lines of code as possible (short of obfuscation of course!). Always keep it in your mind how difficult it would be for the programmer coming along behind you (that coder might be you months or years later).

Happy coding!

 

The code:

Before I refactored:

private int GetDfuCount()
{
int maxCount = 0;
ArrayList systemDFUList = new ArrayList();
foreach (DFULibrary.DFU userItem in GetUserDfuList())
{
if (userItem.Exists == false && userItem.Staged == false)
{
if (!userItem.BusinessUnit.Equals("CASE READY BEEF-PORK"))
{
maxCount++;
}
else
{
if (userItem.Reservation == true)
{
maxCount++;
}
}
}
foreach (DFULibrary.DFU systemItem in userItem.SystemDfuList)
{
if (systemItem.Exists == false && systemItem.Staged == false)
{
bool match = false;
if (!systemItem.BusinessUnit.Equals("CASE READY BEEF-PORK"))
{
foreach (DFULibrary.DFU listItem in systemDFUList)
{
if (systemItem.Product == listItem.Product &&
systemItem.Location == listItem.Location &&
systemItem.DfuLevel == listItem.DfuLevel &&
systemItem.SellingGroup == listItem.SellingGroup &&
systemItem.DriverLevelLoc == listItem.DriverLevelLoc)
{
match = true;
break;
}
}
if (!match)
systemDFUList.Add(systemItem);
}
else
{
if (userItem.Reservation == true)
{
foreach (DFULibrary.DFU listItem in systemDFUList)
{
if (systemItem.Product == listItem.Product &&
systemItem.Location == listItem.Location &&
systemItem.DfuLevel == listItem.DfuLevel &&
systemItem.SellingGroup == listItem.SellingGroup &&
systemItem.DriverLevelLoc == listItem.DriverLevelLoc)
{
match = true;
break;
}
}
if (!match)
systemDFUList.Add(systemItem);
}
}
}
}
}
return maxCount + systemDFUList.Count;
}

After I refactored:

private int GetDfuCount()
{
Func<DFULibrary.DFU, bool> userDfusToCount =
x =>
!x.Exists && !x.Staged &&
(x.BusinessUnit != "CASE READY BEEF-PORK" || x.Reservation);
Func<DFULibrary.DFU, bool> sysDfusToCount =
x =>
!x.Exists && !x.Staged &&
(x.BusinessUnit != "CASE READY BEEF-PORK" || x.UserDfu.Reservation);
int userDfuCount = UserDfuList.Count(userDfusToCount);
int sysDfuCount = SystemDfuList.Count(sysDfusToCount);
return userDfuCount + sysDfuCount;
}

Tags: ,

Information streams

by October 9, 2008 06:12 PM

I was going to send this information to someone and thought I would post it instead.

In order to stay as current as I can with what is going on around the community of development, I basically try to stay current on just a few blogs (below), follow links like crazy, and listen to a few podcasts.

For the blogs, the idea is not to completely absorb all of the material that I read (there’s just too much), but rather just kind of plow through it in hopes of catching general themes and hot topics. Of course, I slow down and read the juicy stuff or topics I’m especially interested in, but I rarely spend much time on any given blog entry. This is especially the case for entries that are rich with actual code. I greatly prefer those entries that talk about something rather than show you to the nth degree with a ton of code samples. I just don’t have the time to spend 10+ minutes (sometimes it takes a lot more time than that) trying to fully grok a single entry.

On to the list! This isn’t the ultimate list perfect for all people. It’s just a list that works well for me at the moment. It actually fluctuates quite a bit over time. If you know your bloggers in the dev community well, you may notice there are a few important ones missing. They come and go. I find that sometimes the “great” ones push out a ton of content and will actually cause my unread posts to just build and build. The last thing I need is another vice hanging over my head saying "Come on Rob! Get out there and read – you're falling behind!" I have definitely been known to go to all items and just mark them all as read – there’s nothing saying you have to catch every one.

One last thing... do not visit these one at a time and try to pick out what is new from the last time you were there. Use a reader. I personally would suggest Google Reader simply because it has worked awesome for me. Use whatever floats your boat though.

Enough jibba jabba already!

Ok now, there has to be an easier way to share feeds. I exported my feeds from Google Reader, but couldn’t quickly find a way to get the opml to render in html, so I typed them all :)

 

Now for your listening pleasure... Podcasts!

In addition to reading way too much, I listen to tech podcasts on the drive to and from work. Even for short drives you’d be surprised how much content you can burn through in a week. Here is that list:

 

And that’s it. All of that is my current information stream. Seems like a lot now that I’ve written it all out like this, but it really doesn’t seem like it. I start my mornings by quickly going through all of the new blog entries. I basically just plow through them quickly and leave the ones I really want to read thoroughly unread and come back to them after the initial plowing. If there’s still time in the morning before I need to get to work, I read a few, otherwise I just read them throughout the day on breaks. The podcasts don’t really take effort at all. I just sync up my iphone and listen to them in the truck. I don’t really set aside special time for them. I’ve tried listening while I work, but my tiny brain can’t concentrate on both coding and the podcast content at the same time. One or the other ends up getting neglected (I’ll let you guess which one ;).

Happy coding!

Tags: ,

My Development Philosophy take one

by May 31, 2008 05:59 AM

Recently I had a discussion with a colleague at work about a way to speak to future developers that join or take over our projects. The idea was that we could simply add a "developer's note" to the solution items so it would live with the rest of the code in source control. I personally couldn't think of a better place for a piece of documentation like this.

After our discussion he spent some time and mocked up a sample developer's note and sent it my way. The idea was that I would customize it to suit me because we came to the conclusion that these developer notes should be a bit personal and should come from the lead developer of the project in question and I happen to be the lead developer on this specific project. All good so far, but in the mock up he include a brief introduction that initially stated his (or a made up) personal development philosophy. Excellent idea I thought. As I started to write my personal philosophy I realized that I didn't have one! I kept writing different things I thought were good ideas only to delete them after thinking that they were just good ideas but didn't really make a very good philosophy. It dawned on me that I have never really sat down to define for myself what I truly believe is a good developer or what makes a good developer or what makes for a good development philosophy. I didn't have a personal mission statement, if you will.

So the research and soul searching began... and this is what I found and the conclusion I came to.

First, some nuggets I found while doing a bit of googling:
Hallmarks of a great developer
Why I’m a better software developer than you
Why Good Programmers Are Lazy and Dumb
How To Become a Better Programmer by Not Programming
Skill Disparities in Programming

The last two are especially good ones. Well, everything from Coding Horror is awesome in my opinion!

Now then, where does all of this leave me? After reading those articles and many others, and after doing a ton of plain old soul searching, I think this should do it:

My personal development philosophy is simple: strive to accomplish the task at hand as well as you can given your current skill set and always strive to improve your skill set.

Now that I look at it, it seems more like a personal philosophy towards life rather than specifically a development philosophy. It also isn't a statement that would help a developer understand the code-base s/he was about to dive into. I guess I'll keep pondering and researching...

Tags: