Archive for June, 2008

An intro to Search Engine Optimization (SEO)

I’m going to assume that a fair number of my readers have a website, blog, or other web presence. Many of you have probably built a website or two. I’m going to give you some quick SEO tips that I have found to be most important.

Success-Chart

Our resident SEO expert spends nearly every day researching the current trends in SEO. If you try to do the same, and you’re the only one running your site, you won’t have any time to improve your site and come up with new content. You need to determine the right balance of time to make your site a success.

  • Define your goals - The first thing you need to do is ask yourself what the purpose of your site is:
    • Are you trying to sell something online?
    • Are you trying to get leads?
    • Is your site simply a place you direct people to for more information?
  • Focus on Google - Google is the by far, the most popular search engine. Most likely, you’ll want to focus your attention on them.
  • Make life easy for Google - If you expect Google to make decisions, you might not like the results.
    • Avoid duplicate content - If you have the same content on more than one page, you may be penalized. At the very least, Google won’t know which content to give you credit for.
    • Make your HTML as simple as possible. A well formed XHTML design will go a long way.
  • Optimize the way your pages look in the search listings - Google will only show the first 60 or so characters in your title, so keep that in mind. Make sure you DO use meta description tags in your pages, because Google WILL use those in it’s listings. Remember, you’re not just optimizing for the Google index, you also want your titles and descriptions to entice users to click on your result.
  • Write original content - Google is looking for original content, and it has often been said that content is king. Even if Google isn’t giving you points for original content, Google is looking for information that is relative to the times. If you’re consistently writing good, original, and up-to-date content, Google will eat it up.
  • Create a sitemap - Sitemaps allow you to give the search engines a "map" to all of your pages, which ensures that they’ll be found as quickly as possible. It also gives you an opportunity to specify how often pages change. If you’re using Wordpress, you can use an automated sitemap generator.
  • Get relevant links - Google is built on a reputation system. When reputable, related sites link to you, Google will realize the popularity of your pages. The best way to get good links is to write good content. Another way is to make friends in the community, that have similar interests. They might be willing to add your site to their blogroll, or mention you in their content.
  • Tell Google what to NOT index - You can create a "robots.txt" file that tells the search engines what they can, and cannot index. You want to filter out all of the pages that are not original content. For example, on this blog, I filter out everything except the front page, about page, and the posts themselves. You can see my robots file here. I have talked about using a robots.txt file to avoid duplicate content in the past.
  • Use the Google webmaster tools - If Google is having problems indexing your site, you’ll certainly want to know why. I check the webmaster tools daily to make sure that there are not any problems.
  • Do what Google asks - Google publishes their recommended webmaster guidelines. You definitely don’t want to do something that Google explicitly forbids. Your playing their game, you need to play by their rules.
  • Have simple URL’s - Your URL’s should be human readable, and more importantly, should be simple enough that search engines won’t get confused. Avoid URL parameters, and instead opt for path or page based names. For example, http://www.yoursite.com/posts/seo-tips.html.

If you have the time to take your SEO skills to the next level, there are immense resources available. The best way to find them is to simply do a Google search. The sites that do the best job with SEO should appear at the top!

A Dependency Injection example with Spring.NET

As requested, here is a real world example of how I used dependency injection to simplify a project, increase modularity, and subsequently increase testability.

Here’s the project. I have a successful website called SimpleTracking.com which allows you to track packages using a simple, common user interface. It also allows you to track pages using RSS.

Here is a list of features:

  • Supports multiple shippers, including FedEx, DHL, and USPS. The tracking number is resolved to one of them, and if a tracking number could belong to more than one, they are called simultaneously, and the one that returns the results is used.
  • Results are cached to avoid overusing the shippers servers
  • Errors are handled appropriately

I boiled the design into a tree of classes:

 image

To greatly simply the design, I decided that each module would implement a common interface. After all, they all take in a tracking number, and return tracking data. Here is the ITracker interface:

public interface ITracker
{
	TrackingData GetTrackingData(string trackingNumber);
}

Simple enough? Every class in the diagram above implements the same interface. If I want to add additional functionality, such as logging for example, I can simply add a class to the chain, and implement the same interface.

Now I can wire it up with Spring.NET:

<object name="postUtility" type="YTech.ShipperInterface.Tracking.Http.PostUtility, YTech.ShipperInterface" />

<!-- The trackers that actually do the work -->
<object name="uspsTracker" type="YTech.ShipperInterface.Usps.Tracking.UspsTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
	<!-- Code removed for readability... -->
</object>
<object name="fedexTracker" type="YTech.ShipperInterface.FedEx.Tracking.FedexTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
	<!-- Code removed for readability... -->
</object>
<object name="dhlTracker" type="YTech.ShipperInterface.Dhl.Tracking.DhlScreenScrapeTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
</object>
<object name="simulationTracker" type="YTech.ShipperInterface.Tracking.Simulation.SimulationTracker, YTech.ShipperInterface" />

<!-- Combine all of the other trackers into one stream -->
<object name="multiTracker" type="YTech.ShipperInterface.Tracking.MultiTracker, YTech.ShipperInterface">
	<constructor-arg>
		<list element-type="YTech.ShipperInterface.Tracking.ITracker, YTech.ShipperInterface">
			<ref object="simulationTracker" />
			<!-- Order these by popularity -->
			<ref object="fedexTracker" />
			<ref object="uspsTracker" />
			<ref object="dhlTracker" />
		</list>
	</constructor-arg>
</object>

<!-- Cache the upstream tracking data -->
<object name="cacheTracker" type="YTech.ShipperInterface.Tracking.CacheTracker, YTech.ShipperInterface">
	<constructor-arg ref="multiTracker" />
</object>

<!-- Handle errors by logging them, and returning a special ErrorTrackingData object -->
<object name="MainTracker" type="YTech.ShipperInterface.Tracking.ErrorHandlerTracker, YTech.ShipperInterface">
	<constructor-arg ref="cacheTracker" />
</object>

Now in my code, this is all I have to do:

var ctx = ContextRegistry.GetContext();
var tracker = (ITracker)ctx.GetObject("MainTracker");
var td = tracker.GetTrackingData("my tracking number");

Every piece I’ve written is fully testable. I even created a class that posts data to a remote web server, and returns the response. This allows me to completely test the tracker classes. They don’t care if they’re hitting against a real server, or an in memory request/response mock class.

I have nearly 100% test coverage, and making changes to the site is a breeze.

The next step is to convert the actual web project to an MVC project so that I can unit test the actual page functionality.

Hopefully I’ve given a good example of how inversion of control can be a really good thing. Have any more questions about the architecture? Feel free to leave a comment.

Note: I haven’t replaced the code on the live SimpleTracking.com site yet, but I plan on upgrading in the next couple of weeks.

Unit tests are for functionality, not code!

Shawn has an interesting post where he talks about why 100% unit test coverage should be one of your goals. I agree 100%. I’m not sure why anyone would say that you shouldn’t be testing your properties. Don’t you want to make sure they work?

Unit-Testing

The prevailing philosophy in regards to unit testing is writing your tests before your code. In practice, this happens a lot less than it should. Why should we write our unit tests first?

  • Writing your unit tests first makes you design pieces of your software from the clients perspective. After all, you’re writing your code to be consumed. The code itself is not important, it’s what it does for other code.
  • Unit tests are meant to test functionality, NOT code! That means if you write your unit tests after the fact, you’re probably not focusing on the functionality. You might be trying to come up with edge cases that might not even matter to the client. It’s harder to come up with good unit tests after the code is written, because you’re not necessarily looking at it from the clients perspective, or from the perspective of the required functionality.

There are two valid ways to increase code coverage:

  • Write additional tests - This only makes sense if you forgot to write the test initially. Since you’re tests are verifying functionality, why don’t you already have a test for this particular piece of functionality?
  • Remove the untested code - In a perfect world, this is what you would always do. After all, your tests verify that your code has a certain set of functionality. If you have untested code, that code isn’t needed. Why keep code you don’t need?

Here is the basic process I recommend:

  1. Come up with a rough design in your head
  2. Write unit tests to test a required piece of functionality
  3. Write the code to provide that functionality
  4. Verify that the unit tests pass, fix the code as necessary
  5. Refactor as necessary
  6. Run a code coverage tool, and get as close to 100% as possible using one of the methods I mentioned previously.
  7. Go to #2 and repeat as necessary

What a developer needs from their manager

I’ve a read a lot of articles talking about what it takes to be a good development manager. There are also articles about what makes a good developer. I thought it would be a good idea to describe what a developer needs from their manager.

Thumbs-Up

A developer abstraction layer - There is so much stuff that goes on in a company, and I really don’t need to know it all. For my own curiosity, give me general interesting tidbits, but more isn’t necessary.

Leave me alone - If you interrupt me for no reason while I’m getting a lot of work done, I’ll obviously get less done. It’s not worth interrupting me just to find out what I’m doing. If I’m walking around, that’s probably the best time to talk to me.

Buy any training materials that I request - Books are cheap compared to my salary. If I can learn something new that will save time, the investment will have been worth it. The same goes for magazines, software conferences, etc.

Be flexible - When it’s time to get some coding done, there are times that I’ll be more productive than others. My computer doesn’t care if I’m using it at 3AM or 10AM. You shouldn’t either.

Trust - If you don’t trust me, you’re setting me up for failure. Trust your employees first, and take appropriate action if they give you reason not to trust them. If I know you trust me, I can focus on getting my job done.

Keep me happy - A happy developer is a productive developer. Sometimes there are small things you can do that will keep me happy. Buy lunch every once and a while. Tell me to go home early on a Friday. As a bonus, I won’t be looking for another place to work if I’m happy.

Guide, but don’t over-manage - You have the big picture, so I need your guidance. That doesn’t mean that you have to know every detail about what I’m doing. You’re not a babysitter, you’re a teammate.

Be accessible - If I get need something, please be available. I may need you to pull in the right resources to solve a problem.

Have answers - You’re the hub of the wheel. If you don’t know what’s going on, you’re useless to me. You need to be organized and connected.

Be able to prioritize - You have a better idea of what is important for the overall product. That means I need you to prioritize features accordingly. That means I’ll always be working on something important.

Tell me what is expected of me - I need to know exactly what is expected of me, and I need to know how you’ll determine if I’m completing what is expected. I also need to know how you’re going to gauge my performance. When it’s time for my review, there should be no surprises.

If you’re interested in more information on this topic, I highly recommend you read "First, Break all the Rules - What the world’s greatest managers do differently". It’s not specific to development managers, but it certainly applies. In that book, they empirically determined the factors that are the most important traits that promote success and happiness:

image

  1. Do I know what is expected of me at work?
  2. Do I have the materials and equipment I need to do my work right?
  3. At work, do I have the opportunity to do what I do best every day?
  4. In the last seven days, have I received recognition or praise for good work?
  5. Does my supervisor, or someone at work, seem to care about me as a person?
  6. Is there someone at work who encourages my development?
  7. At work, do my opinions seem to count?
  8. Does the mission/purpose of my company make me feel like my work is important?
  9. Are my co-workers committed to doing quality work?
  10. Do I have a best friend at work?
  11. In the last six months, have I talked with someone about my progress?
  12. At work, have I had the opportunities to learn and grow?

That book is one of my favorites, and I highly recommend all managers read it.

Are there any other factors you feel are important? Leave a comment and let me know!

I finally get the point of inversion of control

I think I’m finally starting to understand the Inversion of Control principle (aka Dependency Injection). I had a hard time understanding most examples out there, because they appeared to be solving problems that didn’t even seem like real problems to me. For years I’ve been writing classes, testing them, and hooking them together. In many cases, I was already practicing inversion of control. The benefit I wasn’t seeing was the fact that you can separate the modules in your code and the connections between them.

traditional-vs-di

When you really commit yourself to breaking the problem down into manageable pieces, it does create more testable and reusable code. I already knew that, but when you starting using IoC, it really starts to drive that point across. It’s similar to the effect that unit testing has. When you start writing unit tests, you try to make your classes more unit testable. When you start using a dependency injection framework, you try to make your classes more open to injection.

So what is a dependency injection framework? It’s the glue that holds your pieces together. Without it, your classes would probably be dictating the classes that it depends on. With dependency injection, the application configuration tells the class what modules to use. A dependency injection framework separates the linking from the pieces.

ioc diagrams 

In the diagram on the left, it’s a typical tightly coupled design. Every class is hooked up directly to another class. This doesn’t mean that each class isn’t testable, but it’s a very rigid design (which isn’t necessarily avoidable). In general, the easiest unit testing was in the classes on the edges, since they have a usable surface area.

The diagram on the right is closer to what I’ve been creating while using a dependency injection framework. In the first pass, I create pieces that contain my business logic. Then, I can use the dependency injection framework to declaratively define how those pieces are wired together.

At this point, I would have a hard time NOT using something like this. While this concept isn’t new, the frameworks have recently become very mature. Personally, I’m using Spring.NET and loving it. One of my pet projects for package tracking,(SimpleTracking.com) has been rewritten using a modular, test first, dependency injected design philosophy. I was able to reduce the amount of actual code by quite a bit, increase my testing coverage, and decrease the amount of duplicate code.

Sold

I’m sold!