Archive for December 2007

2007 Retrospective

For me, 2007 was mostly about learning the best way to run a development team in a way that adds the best value to the business.

I became convinced that it is not enough to optimize development locally – to achieve the best value, we must treat development as part of a manufacturing-like process. In doing so, we can understand that requirements are like inventory – they go stale and lose value if they sit around. We also can understand that we need to link the day-to-day tasks we do to business value. Finally, how we define “done” is one of the fundamental questions for any development team.

I already was using Scrum, but began experimenting with Kanban Boards. This showed me that sometimes planning meetings are wasted time. Estimating has value only as much as it assists in release-planning. My newly-won experience is invaluable in knowing how much planning and estimating is appropriate for a given situation. I feel like I could easily fulfill the role of ScrumMaster on any team, or else introduce existing teams to more optimal ways of doing things.

One of the lessons I have learned from being a Software Architect is that you cannot always dictate architecture, but you can guide it by providing simple and effective ways to do things. There are some very strong strategies that can be applied to achieve good long-term viability of software. To this end, I registered a new domain (perfectapi.com), and put up a website on that domain. I did not find the time I needed to do it justice though.

My idea was to try and apply my own hard-learned lessons of software development in a way that improved the architecture for others. This is not a pipe-dream – it has been done before, most recently with Ruby-on-Rails. If you can find the correct paradigms, you can quickly create a community that can be very effective at developing new applications.

In 2005, I had decided not to work on web applications anymore. ASP.NET was just too complex, too barebones to develop seriously on. Ruby on Rails is probably ok, but it has a Unix-like learning curve (I’ve grown used to Intellisense). In 2007, Silverlight was introduced. I have not worked with Silverlight yet, but the feeling I get is that it will change the paradigm enough away from the horrible POST-RESPONSE loop of web development.

Personally, it has been a difficult year. My lone-wolf tendencies have hurt family life, and I find myself with too few friends. I have put on weight. Work was all-consuming at times. It is not that I work long hours – it is just that the hours I work are very intense and stressful. Plus, there is just too much to know – it is a truly exciting period in software development.

I will find a new job in 2008. I hope that it will allow me the freedom to relax more with family and friends.

Any Wireless Mouse Recommendations?

I do not have a wireless mouse (nor do I need one), but my wife has one and it is rapidly nearing its end-of-life. I can tell, because of the number of times she smashes it down on the mousepad in frustration. She is not alone in her anger, as evidenced by the large number of mouse smashing videos on you-tube.

Anyway, does anyone have any recommendations? Important characteristics are long battery life and connectivity that is constant (perhaps those 2 things are mutually exclusive?). It only needs range of 2-3 feet.

I already looked at lots of reviews on Newegg and via Google. My favorite is an article entitled Information About A Wireless Mouse. Its my favorite because it manages to say absolutely nothing, in a nice short 5 paragraph article. I wonder whether it was written by a software application?

The importance of Relational Simplicity

I don’t know if others have fallen into this trap – I only know that I have. As such, this post is mostly a reminder to myself for future projects….

When building software that uses a database, it is important not to create what I will call “implicit, difficult-to-resolve relationships”. An unrealistic, but illustrative example…

Suppose you have a database-lookup of zip-codes, such that each zip-code looks up a US state. Suppose then, that you decide to add a time-dimension to those zip-codes, such that each zip-code has a period during which it is valid. In our address table, we store the zip-code. When needed, we can lookup the US state, but each time we do it, we have to factor in some date (because the zip codes are only valid for some period).

It is not always a date (they are the worst though – avoid like the plague). It could be a customer id (customize your lookup tables for each client within the database, but still maintain some common set of values for all clients). If the relationship can no longer be simply resolved, then you have a problem.

It is tempting to add flexibility in this way, but ultimately a mistake. Traversing relationships is done very often in a software system – anything artificial you do to make a relationship more complex than “key = foreign key” has a direct negative impact on system complexity/quality. A good guideline – if your O/R Mapper cannot represent the relationship, then it is too complex (you do use some form of O/R Mapper, don’t you!?).

So, keep your relationships unambiguous (by linking on a key field instead, for example). Even duplicating the data is better – it is far easier to keep multiple copies of a data field than it is to consistently correctly traverse a difficult-to-resolve relationship. Keep the zip-code field if you must, but add an unambiguous foreign key to the related data.

Why fixing bugs is more risky than adding new features

In any well designed software application, one of the fundamental principles we try to abide by is the open-closed principle. Basically, this means that we try and structure the code in such a way that adding new functionality does not require us to change existing code. That is, we strive to add code instead of changing code.

Following this principle dramatically improves quality. The reason is that changing code allows a risk of altering the meaning (semantics) of some part of that code. Because of that, whenever we change code, we run the risk of breaking code that depends on that code.

So how does that relate to fixing bugs? Fixing a bug almost always involves altering the semantics. The old meaning was wrong (buggy), so we need to fix it. This leads to some interesting paradoxes. First…

Fixing bugs is one of the most risky things you can do to a software application.

The better you have followed good design principles, the more this is true. Conversely, in less well designed systems, it is less true…

If you have a poorly designed system, then bug changes are not particularly risky.

This is because in a poorly designed system, all changes are equally risky.

You can mitigate the impact of bug-fixes through the following techniques:

  • reduce dependencies – the less components that are linked to the code being changed, the less risky a change is.
  • regression testing – A regression test will improve the likelihood of discovering breaking changes. Regression tests can take many forms – anything you run daily, (or at the same time as your builds) is a regression test. This includes NUnit-style unit tests, and FIT tests.
  • Code reviews – part of a bug-fix code-review can be to review the impact of the change. Any tool that shows coupling (such as NDepends) can probably help with this.
  • Impact analysis – Pre-identify parts of the system that others depend on heavily. Changes in these parts of the system are particularly risky and need careful attention.