Return Of The Killer Smart Tags

May 21st, 2006

Well maybe not so much "killer"… Anyway, Scoble mentions the return of SmartTags due to bloggers choosing to add them to their site. I pretty much never actually go to bloggers sites unless I want to write a blog post about them in which case I open a new tab in NetNewsWire to remind me for later, so I don't notice them much. When I do see them though they really annoy me - they look far too much like hyperlinks and distract far too much from the content.

It's odd as well that they never feel relevant. Just because a post mentions the word apple doesn't mean I want to buy one (the fruit or the computer). What tends to disturb me more though is forums that use this kind of advertising that I've been seeing a lot. That's putting ads in the middle of your users words and I'd consider it outright unethical.

Now using this technology to provide inline definitions would be useful. Interestingly one of our engineers implemented a system like this as a plug-in for EditLive! for Java with the idea of being able to define glossary terms and have the definition display on the page if it's wanted but be out of the way if not. You can imagine how useful this would be in industries that use a ridiculous number of acronyms and specialized terms.

In fact, on our internal wiki there are a whole bunch of pages dedicated to defining terms and acronyms that are specific to our business which would be really useful to be able to display like this automatically. I find it really annoying to auto-link every capitalized word like most wikis do as it leads to too many links so I'd restrict this to just showing a pop up definition if the page was specifically marked as a definition (or perhaps if it was below a certain length). I'd also change the rendering to something much more subtle than the double green underline that seems to be typically used. Maybe a dotted pastel colour?

Framing The XP Principles

May 21st, 2006

A while back Ben Hyde wrote his thoughts on the key XP principles in What every you doing, it’s wrong! I'm not sure I fully comprehend exactly what Ben is trying to say but a lot of it seems opposed to the way I see XP in theory and to the experience I've had in implementing XP.

I'll start with Ben's rewording of the summary of Extreme Programming (see also James Mead's original):

  • integrate continiously assures you take only small steps
  • writing tests first assumes the code and platform has nothing to say about the problem
  • pairing programmers assures you leave a large swath of good talent for your competors to hire
  • refactor mercilessly assumes you have large code bases rather large installed bases, poor you.

Firstly, integrating continuously, does ensure you take small steps and that's a good thing. Ask Netscape about how successful throwing out an entire code base and rewriting it is. Sure Firefox is becoming popular now, but Netscape has all but gone out of business because of one bad technical decision to rewrite their entire browser instead of taking small steps and fixing the existing one.

There are more benefits to small steps - by taking small steps you get quicker feedback, you know sooner that something is broken and there are fewer changes that could have broken it. You're also less likely to break things in the first place because small steps are easier to fully understand, so it's less likely that you'll miss something.

Most importantly though, taking small steps doesn't mean that you can't make large changes. You just make large changes one step at a time. You can achieve the effect of any large step you might want to take in small steps, with the added benefit that you know sooner if it's not going to work and you may realize you don't need to go the whole way because the benefits are achieved by just doing part of the work.

I'm not sure what the criticism of test first is meant to be - writing tests firsts mean you do a small piece of design up front (by writing a test) and then write the code to execute on that design. When you write your tests you should be considering the strengths and limitations of both the existing code base and the platform you're working with. In addition, you get the ability to verify that your code matches your design and that it does what you think it does by running the tests. That doesn't mean you'll have bug free code, but you will have code that works in all the cases you thought to write a test for, considering you have a test for every branch and every side-effect (or at least you should if you're actually doing TDD) is a pretty high level of quality and provides a lot of confidence in your code.

The pairing programmers rewrite is the biggest falsehood in this list. If you have a good team who actually have social abilities then pairing is fun. Our office comes alive with happy chatter and laughter as people pair because we've built a team that gets on well together and focussed on enjoying our work. Frankly, I don't care how brilliant you are at writing code, if you don't have the social skills to interact with your co-workers you are not a talented programmer, you're a code monkey and I wouldn't want you on my team.

It's not XP that makes communication important, software engineering has always required good communication skills and it's a shame that so many people in the field don't realize that. You almost always have to work with a team in software development, you almost always have contact with other parts of the business and if you want to develop good software, your engineering team should be in regular contact with customers so they understand their problems. Besides which, wouldn't it be nice to have confidence that when your biggest customer has problems you can send one of your developers out to help them fix the problem? You can't do that unless you value social skills when you hire engineers, yet even really big companies value the ability to do just that.

Finally, the refactoring rewrite shows a complete lack of understanding about what refactoring is. Refactoring is not about changing public APIs, it's not about constantly shifting the product under your user's feet. It is about changing the implementation of APIs for the better, without affecting the end result. As Martin Fowler put it, refactoring is "a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior" (Fowler, Martin. Refactoring: Improving the Design of Existing Code. P. 53).

If you are refactoring instead of redesigning, your users will never see the difference except perhaps for a smaller binary size (due to removed duplication in your code) and fewer bugs (due to the code being more maintainable). The functionality of your program, the public APIs and the user interface should all remain unchanged when refactoring.

As an example, Ephox has a very large installed base - not only do we have thousands of clients around the world, most of those clients deploy to a large number of end-users, add in the OEM deals we have and the number of people affected by changes to our product is pretty immense. Even more importantly, we regularly deal with very large enterprise development projects that don't upgrade regularly and have very long test cycles to deal with any changes. If we were to break our backward compatibility we'd get huge numbers of complaints from our existing clients.

Despite that, we refactor mercilessly to keep our code maintainable. In our last major release we completely refactored out HTML list editing code - users would only have noticed that bugs were fixed. In the major release before that, we completely refactored the way we handle loading the editor interface based on the configuration file we're given - none of our clients or end-users noticed, but we did because the new code was far more maintainable. In the next major release we'll have done some refactoring to nearly every part of our code, but it won't affect our public API at all. The only changes users will see are those that we deliberately decided to make because the product manager wanted to improve features or add new features, but all of it is 100% backwards compatible.

It’s worth noting that encouraging refactoring runs counter to the advice to integrate continously. Refactoring is fundimentally a choice to buy a bag of disintegration.

This is also false. You simply refactor in small steps and integrate continuously. You should definitely not be forking a project just to refactor it, you shouldn't even create a separate branch in version control. Refactoring should happen continuously, every day you'll find something that could be better be it because it wasn't perfect when it was first written or because the new code you've added means there are extra demands on its flexibility. Refactoring should just be a routine day to day habit so that you ensure you keep your code base in top condition all the time.

All that said, if you happen to be working on a library instead of a product, refactoring can be more difficult, particularly if you've failed to clearly denote what APIs are intended for public use and which are just available because of limitations of the language you're using. That pain only extends as far as the public APIs though, you should still refactor your internal code mercilessly.