Jon Kruger -
  • About Me
  • Blog
  • Resume
  • Values
  • Presentations
About Me
Blog
Resume
Values
Presentations
  • About Me
  • Blog
  • Resume
  • Values
  • Presentations
Jon Kruger
Uncategorized

Improving your validation code — a refactoring exercise

Today we’re going to talk about validation. Most people have some concept where they validate an entity object before it is saved to the database. There are many ways to implement this, and I’ve finally found my favorite way of writing validation code. But what I think is really interesting is the thought process of the many years of validation refactoring that have got me how I do validation today. A lot of this has to do with good coding practices that I’ve picked up over time and little tricks that allow me to write better code. This is a really good example of how I’ve learned to write better code, so I thought I’d walk you through it (and maybe you’ll like how I do validation too).

In the past, I would’ve created one method called something like Validate() and put all of the validation rules for that entity inside that method. It ended up looking something like this.


public class Order
{
	public Customer Customer { get; set; }
	public IList Products { get; set; }
	public string State { get; set; }
	public decimal Tax { get; set; }
	public decimal ShippingCharges { get; set; }
	public decimal Total { get; set; }
	
	public ValidationErrorsCollection Validate()
	{
		var errors = new ValidationErrorsCollection();
		if (Customer == null)
			errors.Add("Customer is required.");
		if (Products.Count == 0)
			errors.Add("You must have at least one product.");
		if (State == "OH")
		{
			if (Tax == 0)
				errors.Add("You must charge tax in Ohio.");
		}
		else
		{	
			if (ShippingCharges > 0)
				errors.Add("You cannot have free shipping outside of Ohio.");
		}
		
		return errors;
	}
}

The problem with this approach is that it’s a pain to read the Validate() method. If you have a large object, this method starts getting really cluttered really fast and you have all kinds of crazy if statements floating around that make things hard to figure out. This method may be called Validate(), but it’s not telling much about how the object is going to be validated.

So how can we make our validation classes more readable and descriptive? First, I like to do simple validation using attributes. I’m talking about whether a field is required, checking for null, checking for min/max values, etc. I know that there is a certain percentage of the population that despises attributes on entity objects. They feel like it clutters up their class. In my opinion, I like using attributes because it’s really easy, it reduces duplication, it’s less work, and I like having attributes that describe a property and give me more information about it than just its type. On my project, I’m using NHibernate.Validator to give me these attributes, and I’ve also defined several new validation attributes of my own (just open NHibernate.Validator.dll in Reflector and see how the out-of-the-box ones are written and you’ll be able to create your own attributes with no problems). Now my class looks more like this:


public class Order
{
	[Required("Customer")]
	public Customer Customer { get; set; }
	[AtLeastOneItemInList("You must have at least one product.")]
	public IList Products { get; set; }
	public string State { get; set; }
	public decimal Tax { get; set; }
	public decimal ShippingCharges { get; set; }
	public decimal Total { get; set; }
	
	public ValidationErrorsCollection Validate()
	{
		var errors = new ValidationErrorsCollection();
		if (State == "OH")
		{
			if (Tax == 0)
				errors.Add("You must charge tax in Ohio.");
		}
		else
		{	
			if (ShippingCharges > 0)
				errors.Add("You cannot have free shipping outside of Ohio.");
		}
		return errors;
	}
}

When I put these attributes on properties, I don’t write unit tests for that validation. If I was really concerned about whether or not I put an attribute on a property, I could spend 2 seconds going and actually checking to see if that attribute was on the property instead of spending 2 minutes writing a test. It’s just so easy to use an attribute that it’s hard to screw it up. I haven’t been burned by this yet. So already I’ve eliminated some validation code that was cluttering up my validation methods and I eliminated some tests that I would’ve otherwise written.

But my Validate() method still looks messy, and it’s doing a bunch of different validations. The method name sure isn’t telling me anything about the type of custom validation that is being done.

Let’s write some tests and see where our tests might lead us.


[TestFixture]
public class When_validating_whether_tax_is_charged
{
	[Test]
	public void Should_return_error_if_tax_is_0_and_state_is_Ohio()
	{
		var order = new Order {Tax = 0, State = "OH"};
		order.Validate().ShouldContain(Order.TaxValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_tax_is_greater_than_0_and_state_is_Ohio()
	{
		var order = new Order { Tax = 3, State = "OH" };
		order.Validate().ShouldNotContain(Order.TaxValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_tax_is_0_and_state_is_not_Ohio()
	{
		var order = new Order { Tax = 0, State = "MI" };
		order.Validate().ShouldNotContain(Order.TaxValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_tax_is_greater_than_0_and_state_is_not_Ohio()
	{
		var order = new Order { Tax = 3, State = "MI" };
		order.Validate().ShouldNotContain(Order.TaxValidationMessage);
	}
}

[TestFixture]
public class When_validating_whether_shipping_is_charged
{
	[Test]
	public void Should_return_error_if_shipping_is_0_and_state_is_not_Ohio()
	{
		var order = new Order {ShippingCharges = 0, State = "MI"};
		order.Validate().ShouldContain(Order.ShippingValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_shipping_is_0_and_state_is_Ohio()
	{
		var order = new Order { ShippingCharges = 0, State = "OH" };
		order.Validate().ShouldNotContain(Order.ShippingValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_shipping_is_greater_than_0_and_state_is_Ohio()
	{
		var order = new Order { ShippingCharges = 5, State = "OH" };
		order.Validate().ShouldNotContain(Order.ShippingValidationMessage);
	}

	[Test]
	public void Should_not_return_error_if_shipping_is_greater_than_0_and_state_is_not_Ohio()
	{
		var order = new Order { ShippingCharges = 5, State = "MI" };
		order.Validate().ShouldNotContain(Order.ShippingValidationMessage);
	}
}

These tests are testing all of the positive and negative possibilities of each validation rule. Notice that I’m not checking just that the object was valid, I’m testing for the presence of a specific error message. If you just try to test whether the object is valid or not, how do you really know if your code is working? If you test that the object should not be valid in a certain scenario and it comes back with some validation error, how would you know that it returned an error for the specific rule that you were testing unless you check for that validation message?

I could just leave the validation code in my implementation class as is. But I’m still not happy with the Validate() method because it has a bunch of different rules all thrown in one place, with the potential for even more to get added. If I just refactor the code in the method into smaller methods, it’ll read better. So now I have this:


public class Order
{
	public const string ShippingValidationMessage = "You cannot have free shipping outside of Ohio.";
	public const string TaxValidationMessage = "You must charge tax in Ohio.";

	public Customer Customer { get; set; }
	public IList Products { get; set; }
	public string State { get; set; }
	public decimal Tax { get; set; }
	public decimal ShippingCharges { get; set; }
	public decimal Total { get; set; }

	public ValidationErrorsCollection Validate()
	{
		var errors = new ValidationErrorsCollection();
		ValidateThatTaxIsChargedInOhio(errors);
		ValidateThatShippingIsChargedOnOrdersSentOutsideOfOhio(errors);
		return errors;
	}

	private void ValidateThatShippingIsChargedOnOrdersSentOutsideOfOhio(
            ValidationErrorsCollection errors)
	{
		if (State != "OH" && ShippingCharges == 0)
			errors.Add(ShippingValidationMessage);
	}

	private void ValidateThatTaxIsChargedInOhio(ValidationErrorsCollection errors)
	{
		if (State == "OH" && Tax == 0)
			errors.Add(TaxValidationMessage);
	}
}

That’s better. Now when you read my Validate() method, you have more details about what validation rules we are testing for. This is a more natural way of writing the code when you write your tests first because it just makes sense to create one method for each test class.

Then your boss comes to you with a new rule — an Ohio customer only gets free shipping on their first order. This is a little bit trickier to test because now I’m dealing with data outside of the object that is being validated. In order to test this, I am going to have to call out to the database in order to see if this customer has an order with free shipping. How this is done I don’t really care about in this example, I just know that I’m going to have some class that determines whether a customer has an existing order with free shipping.

One of the cardinal rules of writing unit tests is that I need to stub out external dependencies (like a database), and in order to do that, I need to use dependency injection and take in those dependencies as interface parameters in my constructor. But another rule of DI is that I can’t take dependencies into entity objects. This means that I’m going to have to split the validation code out from my entity object. I’ll move them out into a class called OrderValidator, and it’ll look like this:


public class OrderValidator : IValidator
{
	private readonly IGetOrdersForCustomerService _getOrdersForCustomerService;
	public const string ShippingValidationMessage = "You cannot have free shipping outside of Ohio.";
	public const string TaxValidationMessage = "You must charge tax in Ohio.";
	public const string CustomersDoNotHaveMoreThanOneOrderWithFreeShippingValidationMessage =
		"A customer cannot have more than one order with free shipping.";

	public OrderValidator(IGetOrdersForCustomerService getOrdersForCustomerService)
	{
		_getOrdersForCustomerService = getOrdersForCustomerService;
	}

	public ValidationErrorsCollection Validate(Order order)
	{
		var errors = new ValidationErrorsCollection();
		ValidateThatTaxIsChargedInOhio(order, errors);
		ValidateThatShippingIsChargedOnOrdersSentOutsideOfOhio(order, errors);
		ValidateThatCustomersDoNotHaveMoreThanOneOrderWithFreeShipping(order, errors);
		return errors;
	}

	private void ValidateThatCustomersDoNotHaveMoreThanOneOrderWithFreeShipping(Order order, ValidationErrorsCollection errors)
	{
		var ordersForCustomer = _getOrdersForCustomerService.GetOrdersForCustomer(order.Customer);
		if (order.IsNew)
			ordersForCustomer.Add(order);
		else
		{
			ordersForCustomer = ordersForCustomer.Where(o => o.Id != order.Id).ToList();
			ordersForCustomer.Add(order);
		}
		if (ordersForCustomer.Count(o => o.ShippingCharges == 0) > 1)
			errors.Add(CustomersDoNotHaveMoreThanOneOrderWithFreeShippingValidationMessage);
	}

	private void ValidateThatShippingIsChargedOnOrdersSentOutsideOfOhio(Order order, ValidationErrorsCollection errors)
	{
		if (order.State != "OH" && order.ShippingCharges == 0)
			errors.Add(ShippingValidationMessage);
	}

	private void ValidateThatTaxIsChargedInOhio(Order order, ValidationErrorsCollection errors)
	{
		if (order.State == "OH" && order.Tax == 0)
			errors.Add(TaxValidationMessage);
	}
}

Notice that the OrderValidator class implements IValidator. This interface is pretty simple and looks like this:


public interface IValidator
{
    ValidationErrorsCollection Validate(T obj);
}

Now that the validation class has been moved outside of the entity object, I need to know which IValidator<T> classes I need to run when I want to validate an object of a certain type. No worries, I can just create a class that will register validator objects by type. When the application starts up, I’ll tell my registration class to go search the assemblies for classes that implement IValidator<T>. Then when it’s time to validate, I can ask this registration class for all IValidator<T> types that it found for the type of entity that I need to validate and have it do the validation.

I think we could take this one step further. Currently our OrderValidator class is doing three different validations. You could argue that this violates the Single Responsibility Principle because this class is doing three things. But you might also be able to argue that it doesn’t violate the Single Reposibility Principle because OrderValidator is only doing one type of thing. Does it really matter?

What if you got a new validation rule that says that the State property on the Order can only contain one of the lower 48 U.S. states (any state other than Alaska or Hawaii). We also want to add this rule to a bunch of other entity objects that only should use the lower 48 states for their State property. Ideally, I would like to write this validation rule once and use it for all of those objects.

In order to do this, I’m going to create an interface first:


public interface IHasLower48State
{
	public string State { get; }
}

I’ll put this interface on the Order class and all of the other classes that have this rule. Now I’ll write my validation code (after I write my tests, of course!). The only problem is that it doesn’t really fit inside OrderValidator anymore because I’m not necessarily validating an Order, I’m validating a IHasLower48State, which could be an Order, but it also could be something else.

What I really need now is a class for this one validation rule. I’m going to give it an uber-descriptive name.


public class Validate_that_state_is_one_of_the_lower_48_states : IValidator
{
	public const string Message = "State must be one of the lower 48 states.";
	
	public ValidationErrorsCollection Validate(IHasLower48State obj)
	{
		if (obj.State == "AK" || obj.State == "HI")
			errors.Add(Message);
	}
}

Some of you are freaking out because I put underscores in the class name. I put underscores in test class names, and it just seemed natural to use a very descriptive English class name that describes exactly what validation is being performed here. If you don’t like the underscores, then call it something descriptive without using underscores.

Now I change my registration class so that when you ask for all of the validation classes for an entity, it also checks for validation classes for interfaces that the entity implements.

What’s great about is that if an entity object implements IHasLower48State, it will now pick up this validation rule for free. My registration class has auto-wired it for me, so I don’t have to configure anything. I get functionality for free with no extra work! I’m creating cross-cutting validation rules where I’m validating types of entities.

Conclusion

If you made it to this point, you’re a dedicated reader after making it through all of that (or you just skipped to the end). I wrote all of this not only to show how I do validation, but also to show you the thought process I go through and the hows and whys behind how I refactor things and find better ways to write code.

March 11, 2010by Jon Kruger
Uncategorized

Software Engineering 101 – Sat., Feb. 27 – Nashville and online!

Leon Gersing, Jim Holmes, and I are putting on our Software Engineering 101 event this Saturday, Februrary 27 in Nashville. If you’re not in Nashville (and you probably aren’t), you can watch the entire event online on LiveMeeting!

We’ll cover topics like object-oriented programming, the SOLID principles, and code metrics and we’ll spend the afternoon doing some hands-on test-driven development. This event was a lot of fun the first time we did it and I’m really looking forward to it.

You can register for this FREE event here (you need to register if you want to watch online to get the LiveMeeting info).

February 24, 2010by Jon Kruger
Uncategorized

Going independent

Three years ago, my three year plan was to go off on my own as an independent consultant. Well, it’s year 3 and the time has come to make it happen.

For the past four years, I have worked at Quick Solutions and I have loved it. I came into Quick Solutions never having done ASP.NET and ended up getting all kinds of experience in all kinds of different technologies. I never could’ve learned as much as I did and I certainly would not be in this spot today if it weren’t for all of the really smart people that I got to work with.

So what am I going to be doing now? I’m still going to be leading a .NET project for Quick Solutions. There will be plenty of blogging and I have some side business ideas to work on. You will most likely see plenty of me at various community events, lunches, code and coffee, and whatever else is going on.

I don’t know what the future will hold, but I always remember the line in Good Will Hunting where Robin Williams says that he’s going to put his money on the table and see what cards he’ll get. I’m really looking forward to it.

January 22, 2010by Jon Kruger
Uncategorized

Convincing others how to do TDD, OOP/SOLID talks @ CodeMash

If you’re going to CodeMash next week, I’ll be speaking at a couple of sessions. On Wednesday morning, I’ll be doing a PreCompiler session on object-oriented programming and the SOLID principles. I’m not big on 101 level talks, so this will be very little beginner material and mostly advanced OOP ninja stuff. I know this doesn’t sound very sexy, but learning advanced OOP and SOLID has drastically improved the code that I write, which is why I’m talking about it. We’ll do some hands-on coding too, so bring your laptop and get ready to learn from each other.

I’ll also be doing a short 30-minute session on how to convince others to do test-driven development. This is a touchy, difficult task that requires lots of tact, patience, and passion for TDD, but it can be done! I’m not sure what time I’ll be doing this, but check the schedule when you get there and you should find it (it will be in the vendor session timeslot).

January 9, 2010by Jon Kruger
Uncategorized

Why you need to go to CodeMash

This is your annual reminder that you need to go to CodeMash this coming January. I’ve gone the last two years and I look forward to it every year. In three days time you can get exposed to pretty much anything relating to software development, and as far as conferences go, it’s really cheap. So if you want to see why people are making such a big deal about Ruby, or you want to learn how to write iPhone apps, or if you want to learn how to do TDD, or just learn more about what you do at your day job, then CodeMash is for you!

Not only are there great sessions, there are open spaces going on throughout the whole conference. Open spaces are self-organizing discussions where you propose a topic that you want to talk about and put it on the board in a time slot. So not only will you have the great eyes-forward conference sessions, there are several open spaces in each time slot where you can go and talk with other people on whatever topics you can think up. Last year I spent almost the entire conference in the open spaces and I had a great time.

Every year people come from all over the country to come to CodeMash, and last year it sold out. It’s well on its way to selling out again, so go bug your boss as soon as you can and tell him or her that you need to go to CodeMash.

Oh, and I’ll be speaking at the PreCompiler (the first day of the event) on OOP, the SOLID principles, and other “clean code” tips! It’ll be an interactive session when we’ll do some coding and learn from each other, so it should be fun. I know I’m looking forward to it.

Hope to see you at CodeMash!

November 20, 2009by Jon Kruger
Uncategorized

Save time by using IIS instead of Cassini

I’m always looking for ways (whether or big or small) to make the software development process faster, and here’s a real easy win — use IIS instead of Cassini. Cassini was a good idea in concept (allows you to develop web applications without IIS), but it’s also really slow. If you’ve used it, you know what I’m talking about — every time you debug your application, you have to wait 20 seconds for Cassini to start up. Fortunately there is a better way, and that way is to use IIS instead.

The first thing is that you need to be developing a web application, not a web site. I can’t think of any reason to use a web site over a web application. So I’m going to assume that you already have a web application. I’m also using IIS 7. If you’re using IIS 6, you can still do all of the same things, but you have a different IIS console. But you should still be able to figure it out.

Step 1: Create a new application pool by right-clicking on “Application Pools” in the IIS management console. I suppose you could use an existing application pool, but I always like to make a new one. This way, you don’t have one application pool being used for multiple sites, because then you can’t change the application pool settings without affecting all of those sites. After you create the new application pool, click Start in the panel on the right to start the app pool.

Create a new application pool

Step 2: Right click on “Sites” in the IIS management console and select Add New Site. The physical path should be the local path on your drive to the folder that contains the web.config file for your site. In the “Host name” text box, just make up some host name. For example, “dev.mysite.com”. It doesn’t matter what you pick, just pick a host name that doesn’t actually exist. Also, click the “Select” button at the top and select your application pool.

Add Web Site

Step 3: Edit your “hosts” file. This file can be found at C:\Windows\System32\drivers\etc\hosts. Enter this line at the bottom of the file:

127.0.0.1 dev.mysite.com

Use the host name that you entered when you created the new web site.

Step 4: Browse to the URL that you assigned to the site. In my case, http://dev.mysite.com. Your website should come up! Win!

Debugging your site using IIS is slightly different. In Visual Studio, edit the project properties for your web site and select the Web tab. Click on the “Use Local IIS Web Server” radio button and enter your custom URL as the Project Url (e.g. http://dev.mysite.com). Notice that there is also a checkbox that says, “Apply server settings to all users”. Ideally everyone on your team will set up IIS (because this way is much faster), but if that is not the case, you will want to uncheck that checkbox.

Debugging

You can also debug your site by doing Tools / Attach to Process in Visual Studio (that’s Ctrl-Alt-P) and connecting to the w3wp.exe process (aspnet_wp.exe if you’re on Windows XP). If you don’t see w3wp.exe in the list, make sure that you check the “Show processes in all sessions” checkbox in the Attach to Process dialog box.

Happy debugging!

November 7, 2009by Jon Kruger
Uncategorized

I’m speaking on SOLID on Wed., Oct. 28 at the Dayton .NET Developers Group!

Hey everyone in Dayton, I’ll be speaking on the SOLID principles next Wednesday (Oct. 28) at 6pm at the Dayton .NET Developers Group. Hope to see some of you there.

October 21, 2009by Jon Kruger
Uncategorized

Software Engineering 101 Conference Recap

90+ people showed up yesterday to learn loads of good stuff about OOP, SOLID, code metrics, production debugging, and TDD. Judging from the barrage of tweets that I saw today, I’d say the event was a smashing success!! I’m glad to see that so many people found that it was worth spending their day learning about such good stuff.

Props to Jim Holmes, who came up with original idea and did most of the leg work. He won’t take the credit, but he deserves a lot of it.

If you’re looking for the slides from my SOLID talk, you can get them here. (If you’re in Dayton, you can come see me give my SOLID talk at the Dayton .NET Developers Group on October 28!)

September 24, 2009by Jon Kruger
Uncategorized

Controlling your emotions

I’ve been a big sports fan every since I was a young kid, and one thing that always amazes me is how much emotion plays a part in pretty much every sport. For example, in the NBA last year, the home team won 60.8% of the time. If a team were able to block out emotion on the road so that they played as well on the road as they do at home, that would be a huge advantage.

Emotions affect software developers too. I didn’t really think about this so much until I noticed how I was going about things on my current project.

I’m working on a project by myself for a company that has no IT department. So I have to do all of the requirements gathering, design, development, testing, and deployment. I got all of my requirements, I estimated everything out, and I have an Excel spreadsheet where I keep track of how much work I have done and how much I should have done by this point.

I feel like I check that spreadsheet every day to make sure that the number of days of work I’ve completed is higher than the “where I should be” number. Now this isn’t all bad, it’s good for me to know where I’m at and if I’m behind. But this obsession is leading to other odd behavior.

For example, I’ve had the server I’m going to deploy on for months and I keep putting off setting it up. I didn’t conciously think this, but setting up the deployment server wouldn’t make my “hours finished” number go up in my spreadsheet, even though I obviously have to set up the deployment server sometime. So because I wanted to bump up my “hours finished” number, I would do feature development.

A couple weeks ago, I had a couple features drag on several days past the estimate I had for those features, and that was a really hard week. Not because I was in real danger of getting behind, but I was week ahead of schedule in my spreadsheet before the week and I was right on schedule after the week (I didn’t get to cross anything off that week). I felt stressed out all week.

Why was I so upset? I wasn’t even behind schedule! In reality, I ran into a feature that took longer than the estimate, while earlier in the project I had features that took less than the estimate. It really shouldn’t be a big deal.

I realized that I am addict — an addict to getting things done. We all want to be able to cross a feature off the list, and we feel like we haven’t accomplished anything on the feature until we do so.

If you want to see what a developer under pressure, Estimatingwatch what happens when the amount of time they’ve spent on a feature exceeds the estimate. I’ve seen developers get extremely flustered in this situation. They get irritable, they worry that someone is looking down on their performance, and often they cut corners. And for what reason? Because of an estimate, just a guess of how long something is going to take!

An estimate should have no effect on how long a feature should take. If a feature is going to take 3 days to develop, it doesn’t matter if it were estimated at 1 day or 15 days, it’s going to take 3 days. Period. If you stop writing unit tests once you’re over the estimate just to get it done, you’re doing everyone on the project and yourself a disservice.

The addiction to getting things done manifests itself in other ways. I’ve seen situations where developers could’ve spent 5 minutes installing a tool or an update that would’ve saved them loads of time over the course of a project. But they feel like they’re too busy to stop for 5 minutes and install it, so they continue doing it the slow way. These are completely logical people making very illogical decisions.

Other people won’t take the time to learn a new tool or a new technique like TDD because they would have to slow down to learn it. Sometimes this is valid (we all have deadlines), but if you honestly think that something might be able to save you lots of time in the long run, isn’t it worth spending a couple days looking into it? It might work out, and it might not. But if it doesn’t work out, all you’ve lost is two days, and if it doesn’t work out, it might revolutionize the way you write software.

I guess my point is be aware of your emotions and how they affect the way that you work. Don’t let your emotions control you and cause you to make illogical decisions. And please remember, that an estimate is just that — an estimate!

September 2, 2009by Jon Kruger
Uncategorized

Facilitating change

We’ve all worked with people who are adverse to change. Getting people to change and helping them to change is very difficult. The challenge is to convincing people of the need to change without tearing them down.

People always have a reason for doing things the way that they do them. I personally love ASP.NET MVC and I think that it makes software development much easier and must faster. Other people are scared of MVC because they are very comfortable with WebForms. I write tests all the time, but other people have no desire to write tests. But we all have a reason (whether good or bad) that we do things the way that we do them. The challenge is finding a way to give people a reason to change.

The fact of the matter is that many people are adverse to change. This could be for several reasons.

1. They don’t know change is an option. Every year I look back at how I wrote software a year ago and there is always something that I can’t believe that I did a year ago. A year ago I thought I was a good developer. Was I a good developer a year ago? I think I was, but there is always something that you aren’t aware of that can help you. Everyone is at different stages, and not everyone is at the same place as you. This does not necessarily mean that they are stupid or ignorant or that they don’t care, maybe they just haven’t come across something yet.

2. They don’t know why they should choose change. If you’ve been doing WebForms for the last 5 years, you probably feel that you’re pretty good at it. So why should you adopt ASP.NET MVC? I mean, is ASP.NET MVC really beneficial or just another technology that you have to learn? That is a completely legitimate question to ask, and many people are asking it these days.

If you’re trying to get someone to adopt ASP.NET MVC (or any other technology that is new to someone), you need to become a salesman. You need to sell that person on why said technology or way of doing things is going to help them. “This is the right way to do it” is not going to work. That doesn’t tell them how it’s going to help them. You need to convince them that the new way will make their life easier and then show them how to do it.

3. They don’t know how to go about changing. The best example of this is teaching people how to write unit tests. First you have to write your code so that it is testable, which means that you need to understand dependency injection and some DI container like StructureMap. Then you have to learn how to use a mocking framework like Rhino Mocks. You have to learn the difference between a unit test and an integration test, and ideally you will also learn how to write tests first. Yikes, that’s a lot of stuff to learn! The only way that I learned it all was by working with other people that knew how to do it and taught me how. So your colleagues may be willing to change, but they might just need some guidance (or a lot of guidance). They also have deadlines and don’t want to risk being late because they were trying to learn something new. This is where you need to convince them that writing tests will same them time and make their life easier because they will write less bugs and it will be easier to make changes to their code.

4. They don’t want to change. Many people are adverse to change and that’s just their personality. Other people are stubborn and don’t like people telling them that they’re wrong. These people are the difficult ones to deal with. Sometimes all of your efforts with these kinds of people will not succeed, but at least you can make an effort. I think it goes back to showing people why they should change — that there is another way to do things that will make their lives better. But getting them to this point will take a lot of patience and encouragement along the way.

Most people don’t change overnight. Even if someone wants to adopt all kinds of new technologies and practices, it may take them a long time. So give them something small to change. Instead of trying to totally rewrite their entire codebase, show them how to take a feature and write tests for it. Show them how their tests give them peace of mind because they know their code is working. Now hopefully you’ve won some more trust and can move on to bigger problems.

If you’re one of the people who is nervous about change, realize that in this industry things are constantly changing. No one can keep up with it all and know everything, so we need to rely on the expertise of others and learn whatever we can from whomever we can. It may require checking your ego at the door and realizing that you may not know the best way of doing something.

Changing might be hard work. It’s much more comfortable to do something that you know well. But nothing worthwhile is ever achieved without hard work. I promise you, you will be much better off in the end and you’ll be glad that you changed.

July 13, 2009by Jon Kruger
Page 5 of 6« First...«3456»

About Me

I am a technical leader and software developer in Columbus, OH, currently working as a Sr. Engineering Manager at Upstart. Find out more here...

I am a technical leader and software developer in Columbus, OH, currently working as a Senior Engineering Manager at Upstart. Find out more here...