Code Smells (from Fowler)
A code smell is a "surface indication" that there may be a deeper problem with your code. It is very useful to know these, especially when practicing TDD.
UPDATES:
1/28/2010: added Code Smells and re-ordered list
We've spent a lot of time working on this feature, we're out of budget, it works fine in 90% of the cases, and we can just add this little hack that will take care of the other 10%. Therefore it makes more sense for us to just do the little hack.I'm sure you've seen this line of thinking before, so you're already anticipating that I'm going to say this is stupid. But hold on. Its not stupid. This is actually totally sensible thinking, but there are two problems:
A looooooooong time ago I wrote a post called Theory of Software Usability. This post was primarily about the tradeoff between “Ease of Learning” and “Ease of Use.”
I used my favorite example of Vim vs. Notepad. Vim is an advanced modal editor that a n00b wont even be able to get text into if they don’t know what they’re doing. Whereas Notepad is just about the simplest application you can imagine that anyone can figure out how to use.
My argument was that Vim is extremely usable but difficult to learn while Notepad is extremely learnable, but not really all that usable. So there is an implicit tradeoff between Learnability and Usability.
Recently I have been reading The Design of Everyday Things and I can across a concept that is an interesting corollary to the Usability vs. Learnability issue. The book presents “The Tradeoff between Knowledge in the World and in the Head”. Knowledge in the world is simply information that is readily available in the world, so you don’t have to learn it, or at least you don’t have to learn too much. In The Design of Everyday Things an example of a typist is used.
“Many typists have not memorized the keyboard. Usually each letter is labeled, so nontypists can hunt and peck letter by letter, relying on knowledge in the world and minimizing the time required for learning. The problem is that such typing is slow and difficult… But as long as the typist needs to watch the keyboard, the speed is limited.
If a person needs to type large amounts of material regularly, further investment is worthwhile: a course, a book, or an interactive computer program… It takes several hours to learn the system and several months to become expert. But the payoff of all this effort is increased typing speed, increased accuracy, and decreased mental load and effort at the time of typing.”
At the end the book presents some tradeoffs between knowledge in the head and in the world in terms of 5 properties, retrievability, learning, efficiency of use, ease of use at first encounter, and aesthetics. It breaks down like this, knowledge in the world is retrievable, requires little to no learning, is not efficient, is easy to use at first encounter, and can be unaesthetic and inelegant. On the other hand, knowledge in the head is not retrievable, requires lots of learning, is efficient, is not easy at first encounter, and can lead to better aesthetics. So basically, they are at odds with each other.
Bringing back my Vim vs Notepad example, we can see how this fits right in. Notepad puts all the knowledge you need “in the world.” All the labeled keys on your keyboard do exactly what you’d expect and the other functions are clearly labeled in the menus. In Vim on the other hand, you can’t even enter text until you learn the “i” command. The knowledge must be in your head. All the tradeoffs listed above apply perfectly to this example.
I think this is a very important concept to keep in mind when doing software design. Who is your user? What job are they doing? Often often will they be doing that job? Will new people need to figure it out on the fly, or will the same people always do it over and over again? The answers to these questions will help you decide if you should emphasize knowledge in the world or knowledge in the head. If you are building a public facing website that many people will visit, you want to emphasize knowledge in the world. If you are building an application for something like data entry you may want to emphasize knowledge in the head.
The important thing to take away from this is that there is a tradeoff and you have to make a decision one way or the other. Knowledge in the world is not always better than knowledge in the head, and vice versa. Pay attention to what you are building and who you are building it for and design accordingly.