Apr 11
Know your tools
icon1 Darrell Mozingo | icon2 Musings | icon4 April 11th, 2011| icon34 Comments »
Tools

How many carpenters do you think don’t know about kerf widths? How many plumbers don’t know the difference between MAPP and propane for soldering? Probably not many.

Masters of their craft know their tools inside and out. They don’t just skirt by barely knowing how to use them, and end up taking longer to complete a job because of that. We have the same situation in our craft. We use tools day in and day out - our IDE’s, debugging tools (for our main languages and web based ones), OS, browsers, websites, etc. They’re all tools of our trade. Learning how to really use them is just another stepping stone on the path to being a craftsman.

The best way to really make use of your tools and increase your programming speed is to ditch the mouse. Use the keyboard as much as possible, which can be almost everything. Really get good with the keyboard and you’ll be amazed at how much more efficiently you can pump out code and navigate around.

I use Windows and Visual Studio, so I’ll use that as an example. Visual Studio itself has a metric ton of built-in keyboard shortcuts, but add ReSharper to the mix, and you’re golden. Check out the keyboard shortcut cheat sheet, it’s ridiculous, and overwhelming. Pick one or two shortcuts you think you’ll use, then use those exclusively for a week. Make sure to purposely use them as much as possible until they become muscle memory. It won’t take long.

Look at Tools -> Settings -> Keyboard. There’s lots of stuff you can key bind on your own that doesn’t come setup by default. Create a key combination to run your unit tests rather than reaching for the mouse. If a default key combo feels unnatural for you, rebind it. Find something that works for you, and don’t be afraid to experiment.

Start learning keyboard shortcuts in other programs you use on a regular basis. There’s cheat sheets for GMail and Google Reader. For your mouse-free text editing needs (and IDE needs if you’re super experimentative and working with .NET) there’s the grand-daddies themselves: VIM and Emacs. There’s even plugins for Firefox (Vimperator) and Chrome (Vimium) to make each browser navigable in a VIM-esque way, and other plugins for each browser to simply add more keyboard navigation tricks. Heck, there’s even a few VIM plugins for Visual Studio itself if you want to go all the way, including ViEmu (paid) and VsVim (free).

It’s also super helpful to get a keystroke launcher on your box, such as Executor (my personal favorite) or Launchy. These guys basically give you the standard Windows Run dialog on steroids - letting you make custom launch commands and scripts. Definitely play around with one of these and work it into your normal workflow. I find myself leaning on it all the time.

So start practicing with a keyboard-only setup today. Disable your mouse driver and force yourself. It’ll kill your productivity in the short term for sure, but it’ll pay dividends every day for the rest of your career once you get used to it. You’ll thank me in a few weeks. Seriously, I’m marking my calendar.

Mar 31
Canton Software Craftsmanship
icon1 Darrell Mozingo | icon2 Events | icon4 March 31st, 2011| icon3No Comments »

The next Canton Software Craftsmanship meeting is this Monday. We’ll be going over TDD basics by having everyone follow us along on simple exercises.

Register here if you’e interested.

Hope to see you there!

Mar 8

Thanks to everyone that attended the first Canton Software Craftsmanship meeting this past Monday. It was a great turn-out (around 33 people?) and everyone seemed genuinely excited to see where this goes, myself included. Good food and good discussions all around. Sign up for the next meeting on April 4th if you haven’t already, and be sure to spread the word to anyone that might be interested. Remember, we’re about the practices, not the language, so everyone’s welcome.

I’d also like to thank Brandon Joyce and John Hoover for doing a great job with the logistics needed to get this group off the ground. Great job guys!

Mar 4
Taskie runner is now bundled
icon1 Darrell Mozingo | icon2 Taskie | icon4 March 4th, 2011| icon3No Comments »

The latest version of Taskie (which is available on NuGet) now comes bundled with a console runner. Simply implement ITaskieServiceLocator with your IoC container of choice, and put your compiled assembly with that implementation in the same directory as Taskie.exe. Taskie will pick up on the implementation and use it like normal.

This should reduce the usage overhead if you don’t feel like creating a virtually empty console project in your application, and lower the getting started barrier even more. If you’d still like to host your own console application for Taskie, that option will continue to be supported and its usage hasn’t changed.

Mar 2

The problem

We try to strongly type everything in our MVC project, especially URLs. It’s pretty easy to do using all the build in functionality of ASP.NET MVC along with some lovin’ from MvcContrib, but the one situation we’ve always had problems with was client-side javascript. If it’s a basic action call with no arguments, we’re golden (using <%= Html.BuildUrlFromExpression(x => x.MyAction()) %>). It gets tricky when we have a slightly more complex action though:

1
2
3
4
5
[AcceptAjax]
public string DoSomethingComplex(int id, string accountNumber, int amount)
{
	return string.Format("id = {0}, accountNumber = {1}, amount = {2}", id, accountNumber, amount);
}

If we wanted to do an AJAX call to this bad boy, we’d unfortunately have to resort to string concatenation to build up the URL:

1
2
3
4
5
6
// get these values from form fields or something...
var id = 3;
var accountNumber = "123456";
var amount = 325;
 
var ugly_url = "/Home/DoSomethingComplex/" + id + "?accountNumber=" + accountNumber + "&amount=" + amount;

Booo creepy magic strings. Renaming the action name or any of the parameter names left us relying on either ReSharper’s ability to catch the change, manual search and replace, or hoping we had a UI test hitting the page to catch it. Basically, nothing too terribly reliable to keep our app in working order. The more you worry about small changes breaking your application, the less likely you are to refactor it. The less you refactor, the faster your application degrades into nastiness (code not matching up with current business conventions, etc), and the slower you are to respond to change. Not cool.

The solution

Before I go further, I should probably throw up this disclaimer: We use the default routes for everything. The application is behind a login page, and we have no need for fancy SEO friendly URLs, so the solution I’m about to show caters to that scenario. If your application leverages custom routes, you’ll either have to tweak this solution to your needs, or figure out something else. Sorry.

In a nutshell

You’ll end up being able to build the URL above like this:

1
2
var beautiful_url = "<%= Html.UrlTemplate<HomeController>(x => x.DoSomethingComplex(Any<int>.Arg, Any<string>.Arg, Any<int>.Arg)) %>"
						.substitute(id, accountNumber, amount);

This’ll produce a URL template like "/Home/DoSomethingComplex/{0}?accountNumber={1}&amount={2}" on the client. You then plug in the template’s holes with your client-side values. Pretty simple, really.

There’s a few server and client-side pieces to this puzzle.

Server-side portion

The heart of this solution (and the biggest chuck of code) is the actual building of the URL template.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
private static bool onlyTakesInSingleViewModel(string[] routeValues)
{
	return (routeValues.Length == 3 && routeValues[2].ToLower().EndsWith("viewmodel"));
}
 
public static string UrlTemplateFor<CONTROLLER>(Expression<Action<CONTROLLER>> action) where CONTROLLER : Controller
{
	var routeValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action);
	var actionPath = string.Format("/{0}/{1}", routeValues["Controller"], routeValues["Action"]);
 
	if (routeValues.Count > 2)
	{
		var routeValuesKeysArray = routeValues.Keys.ToArray();
 
		if (onlyTakesInSingleViewModel(routeValuesKeysArray))
		{
			return actionPath;
		}
 
		if (routeValuesKeysArray[2] == "id")
		{
			actionPath += "/{0}";
		}
		else
		{
			actionPath += "?" + routeValuesKeysArray[2] + "={0}&";
		}
 
		var placeHolderCounter = 1;
 
		if (routeValues.Count > 3)
		{
			if (actionPath.Contains("?") == false)
			{
				actionPath += "?";
			}
 
			for (var i = 3; i < routeValues.Count; i++)
			{
				actionPath += routeValuesKeysArray[i] + "={" + placeHolderCounter++ + "}&";
			}
		}
 
		actionPath = actionPath.TrimEnd('&');
	}
 
	return actionPath;
}

This method (which has unit tests in the sample project provided at the end of the post) basically builds up the URL template by leaning on a method inside the MVC Futures assembly to get the controller, action, and parameter names. This is the portion you’d have to tweak if you use different routing rules.

Then it’s simply a matter of wrapping the UrlBuilder call with an HTML Helper extension method:

1
2
3
4
5
6
7
public static class HtmlHelperExtensions
{
	public static string UrlTemplate<CONTROLLER>(this HtmlHelper htmlHelper, Expression<Action<CONTROLLER>> action) where CONTROLLER : Controller
	{
		return UrlBuilder.UrlTemplateFor(action);
	}
}

Looking at the example of using this method above, you can see all the parameters in the UrlTemplate call replaced with calls to an Any class. Technically speaking, whatever values you put in the expression passed to UrlTemplate will be ignored. You can put in nulls for references & nullable types, 0’s for value types, etc. I decided to drive home the point to anyone looking at the code that we don’t care what value they provide by making a very slim class that provides the default value for whatever type is needed:

1
2
3
4
5
6
7
public class Any<T>
{
	public static T Arg
	{
		get { return default(T); }
	}
}

It drives home that whole not caring point pretty well, but it’s also a bit wordy, especially if there’s 3 or 4 parameters that need specified. You can omit using the Any class and just give dummy values if you want. Your choice.

Client-side portion

There’s not a whole lot to the client-side portion. Basically a very simple version of the .NET Framework’s string.Format method (which you’ll probably want to put in an external js file and reference as needed). It’s written as an extension on the string type to make reading the final product a bit more natural:

1
2
3
4
5
6
7
8
9
10
11
12
13
String.prototype.replaceAll = function (patternToFind, replacementString) {
	return this.replace(new RegExp(patternToFind, "gi"), replacementString);
}
 
String.prototype.substitute = function () {
	var formatted = this;
 
	for(var i = 0; i < arguments.length; i++) {
		formatted = formatted.replaceAll("\\{" + i + "\\}", arguments[i]);
	}
 
	return formatted;
}

That’s it. Using all these pieces together gives us the final product:

1
2
var beautiful_url = "<%= Html.UrlTemplate<HomeController>(x => x.DoSomethingComplex(Any<int>.Arg, Any<string>.Arg, Any<int>.Arg)) %>"
						.substitute(id, accountNumber, amount);

You can provide the values for the URL template from client-side code, or from your ViewModel by just outputting the value in the proper spot (i.e. use <%= Model.Id %> rather than the client-side id property). This setup has proven very helpful and quite versatile for us so far.

Potential pitfalls

Having shown all this, there are a few potential pitfalls you need to be aware of:

  1. The building of the URL template is pretty rudimentary. It also relies on a method inside the MVC Futures assembly, which I haven’t checked to see if it even exists in MVC3, let alone in future versions. I couldn’t find anything in the main MVC assembly or MvcContrib to fill my needs. Having said that, it’s isolated to one location and we could always get the controller, action, and parameter names by hand with a little expression tree walking, especially since we’re already limited to the default route setup and therefore know where they’d be with pretty good certainty.
  2. This allows you to rename controller, action, and parameter names with complete confidence. However, if you switch parameter positions around, especially if they’re the same type, you might run into a problem. In my usage example above, for instance, switching the id and amount parameters around would still compile and technically run, but the Javascript would continue passing the id in for the amount parameter and vise-versa. You don’t usually switch around parameters for no reason, but it’s worth noting, as you’d have to do a find usages and make sure all the calls are updated properly. At least you’d be able to find all the usages with certainty, though.

Conclusion

Next time you find yourself needing to concatenate strings on the client-side to call URLs, think about using this technique (or something similar) to keep it all strongly typed. If you’re going to work in a static language like C#, you might as well leverage it as much as possible. Strong typing lets you refactor with full confidence that no references to the rename will get left behind by mistake.

You can grab a copy of the source code for the project right here (built with MVC2). Give it a spin and let me know if you have any problems, or if you know a better way to do this without building the URLs by hand.

Feb 24
Canton Software Craftsmanship
icon1 Darrell Mozingo | icon2 Events | icon4 February 24th, 2011| icon3No Comments »

Brandon Joyce and I are starting a Software Craftsmanship group in the Canton area. Appropriately titled Canton Software Craftsmanship, it’ll be the first Monday of every month starting at 6pm in Stark State’s auditorium. You can get more information at the group’s website, here.

If you’re interested in attending, please register so we have a head count for the provided pizza & drinks.

Hope to see you there!

Feb 1
Taskie - Lowering the entrance barrier
icon1 Darrell Mozingo | icon2 Taskie | icon4 February 1st, 2011| icon3No Comments »

One more step to lowering the entrance barrier for Taskie is complete:

Taskie NuGet Feed

Taskie is available on the official NuGet package feed. Build configurations are pending on CodeBetter’s TeamCity server as well.

Next up: ability to log when tasks run, and query that information for later use.

Jan 6
Goals
icon1 Darrell Mozingo | icon2 Goals | icon4 January 6th, 2011| icon31 Comment »

Man, that was a quick year.

Books

  1. Code Complete - Steve McConnell - Not started.
  2. Patterns of Enterprise Application Architecture - Martin Fowler
  3. Applying Domain-Driven Design and Patterns - Jimmy Nilsson
  4. Working Effectively With Legacy Code - Michael Feathers

Tools/Techniques/Processes @ Work

  • Move from SVN to Git (and learn more about Git in the process). - I’ve been using Git for side projects, but not at work quite yet, so I’ll call this half complete.
  • Move from CC.NET to Team City for our build server.
  • Build a more robust build script and management process - including production deployment and database migration scenarios.

Involvement

  • Develop an idea I was given for an open source project and get it live to see what happens. - Taskie
  • At least 24 blog posts (I’m not going to say 2 per month as I’m getting married this summer and I’m certain I won’t be able to maintain a schedule around it). - I got 18 out - not too bad.
  • At least 3 feature/patch submissions to open source projects. - Not started.

Coding

  • Get a version 1 out there on at least 1 of the 3 product ideas I have floating around. - Not started.
  • Keep working on a good working knowledge of Ruby & Ruby on Rails (and use it to build the product mentioned above). - More reading and playing, but no actual project.

So that’s an overall success rate of 58% assuming each goal has equal weight (which they really don’t, but it saves time). Not that impressive, but probably a bit better than average. My goals are pretty similar to these for 2011, just sub out some technologies and books. I’ve grown tired of updating them and I’m sure you’ve grown tired of ignoring the posts in your feed reader, so I’ll just call it quits with publicly posting these goals from here out.

You’re welcome :)

Jan 4
Taskie - now with NuGet goodness
icon1 Darrell Mozingo | icon2 Taskie | icon4 January 4th, 2011| icon3No Comments »
NuGet

In addition to a few small bug fixes, Taskie is now filled with NuGet-y goodness (or should that be the other way around?). Anyway, you can grab the package to use locally right here (with instructions on how to host it locally). I’m working on getting it into the main NuGet package feed in the next week or two.

As part of this release, I’m merging StructureMap into the main assembly so you only have to worry about a single Taskie.dll assembly. I’m also going to see about getting this project on Code Better’s Team City setup for some continuous building lovin’. When that’s done, I’ll provide packages for both merged and unmerged flavors, just in case you need them separated out for whatever reason.

Next up on the list is adding task logging, along with the ability to see when a given task was last run (some of our accounting procedures depend upon the last date they were successfully run, so knowing this programatically is a must for us, and will come in handy for future features as well). Not sure how I’m going to go about it - perhaps a pluggable interface for your own implementation, a connection string you provide, or maybe Taskie’s own internal Sqlite/Raven database. I’ll have to play around with the options a bit.

Dec 27
Testing tips
icon1 Darrell Mozingo | icon2 Testing | icon4 December 27th, 2010| icon3No Comments »

Just some quick testing tips I’ve found helpful over the last few years.

Naming

Don’t name variables company1 or company2. There’s a reason you’re creating two of them - why? Names like companyMatchingCriteria or companyWithCorrectAddressAndWrongPhoneNumber make a lot more sense when reading the tests later. When it comes to testing, readability is paramount, even more so than perhaps the production code.

Unreadable tests lead to developers ignoring them, which leads to false positives, which leads to deleting the tests, which leads to, um, purgatory, I suppose. An alternative is the good hearted developer that spends a disproportionate amount of time understanding and fixing a handful of tests when they only changed a few lines of production code. Either option isn’t appealing, and goes against one of the reasons for testing in the first place.

Intent

When naming tests, either the test names themselves, variable names, or whatever - always go after the business intent rather than the technical reasons. So rather than Should_break_out_of_the_loop_when_an_employee_address_is_null, for example, try something like Should_not_process_employees_that_have_not_entered_their_address. You can picture how these would mean the same thing in the production code (probably a simple null check), but one talks about breaking out of loops and null values (technical), while the other talks about not processing and non-entered values (businesses). The differences often aren’t this obvious either, and I know we developers love talking technical, so it’s pretty easy to let that creep into our testing language.

This helps in a few ways:

  1. Writing the code - if you can’t pin a business reason to a certain bit of code to exist, it probably shouldn’t. I know it’s always tempting to throw extra checks in here and there, but if the businesses doesn’t need it for a certain reason, it shouldn’t exist (exceptions obviously exist). Maybe you’re checking for null employee addresses, but when talking to the business folks, they want the user to enter an addresses when they create the employee. This leads to the employee never existing without an address, and negates the need for the check in the first place. If you were just checking for a null, you’d never think to ask this and it’d always be there.
  2. Maintaining the code - I hate reading code that does a bunch of checks (null, certain values, empty strings, etc), and you come to figure out after working with it for a while that the checks aren’t even needed because of invariants in the system (i.e. those values can never fall into that state). It’s just extra code to read, mentally parse, consider in different situations, and perpetuate - “well, that method checks this for null, so I should too”.
  3. Talking with the business folks - when they come to you and ask what happens if the employee hasn’t entered an address yet, you can look through the tests and see they’re not processed this this location or that for whatever reason. This saves you from having to look for null checks in the testing names and figuring out what it means in different situations. This is a bit of a contrived example for this point, but you get the idea. The tests correspond to how the business people think about things.

So, business intent in test naming = good, technical jargon = bad. Again, exceptions do exist, so this isn’t set in stone all the time.

See a theme with all my recent tips? Naming. That’s why Phil Karlton famously said:

“There are only two hard things in Computer Science: cache invalidation and naming things”

Very true.

« Previous Entries Next Entries »