...is that no matter how great you think your code is, it ultimately sucks. At some point in time, the "great" code that you think you're writing will ultimately cause pain on somebody else.
The Gift That Keeps on Giving
Code is a lot of fun to write, but the more code you write, the more suffering you inflict upon others. I can't begin to stress enough that the mere presence of code itself is a symptom of a problem. It means that you had to write something because whatever requirements that you had to meet couldn't be done using the existing code that you have at your disposal. In other words, you're writing code to solve a preexisting deficiency, whether it was a deficiency on someone else's part, or your own.
Isn't it i.Ronic()?
This has to be the greatest irony of software development: we (as developers) write code to solve other people's problems, but the more code we write, the more problems we inflict on other developers that eventually have to maintain our code. In the end, someone out there has to maintain that 'wonderful' solution that you thought you wrote in yesteryear. In the end, someone else has to write their own version of your library because you had some deficiency in it that was too complicated to fix. That new library, in turn, will eventually fail to solve another problem, causing another developer to write another application to solve the new problem that couldn't be fixed using any other means.
The Path of Suffering
It's a vicious cycle that never ends, and at some point, this pain of maintenance that we inflict on other developers must somehow end. A naive solution to this would be to stop writing code altogether, but it still doesn't solve the problems that we as developers ultimately need to solve. We still need to write code in our daily lives to pay the bills, and people will still need us to write software so that they don't have to do all their work by hand. In other words, it's a necessary evil that perpetuates itself. We cannot avoid the fact that our jobs (by definition) require us to write more and more code--and that's exactly the problem. Code begets even more code, causing the suffering to continue.
Code Nirvana, and the Path of Enlightenment
This cycle seems complicated and nearly impossible to fix, but the solution is ridiculously simple: write less code.
In general, there are a few ways to do write less code:
- Design Patterns
- Refactoring
- Keeping it simple
Design Patterns - A Panacea?
Unfortunately, there are some people out there that think that implementing a particular design pattern automatically leads to less code. That's not always the case. The more patterns you add to your application, the more suffering you inflict on those who have to maintain it and those who use it, and that still doesn't solve the problem of ending the suffering altogether.
It means that if you need to use multiple design patterns in your applications, more often than not, your code is far too complicated to write using the simplest possible means. Design patterns exist to simplify code, and if you find yourself scrolling through thousands and thousands of lines of code in multiple source files to figure out how your 'cool' pattern works, then you're defeating the original purpose of having those design patterns altogether: simplicity.
if (complexity == null) {
For me, it's always a pleasure to see someone else write something so simple that I don't have to waste any more than five minutes trying to figure out how to use their code. Unfortunately, such moments rarely ever occur for me, and more often than not, I find myself having to wade through pages and pages of their code or documentation (or both) to do something that's supposedly 'simple' to do using their software--and that assumes that they even write documentation at all.
Yet again, it becomes even more ironic because it seems that the same developers who write documentation for their code are actually compensating for the fact that their code is so complicated that it needs documentation in the first place. Even I have to admit that I'm guilty of this myself, given that I wrote a series of articles that describes how to use LinFu. It's certainly not as simple as I would like it to be, and in my opinion, admitting that it can be made simpler (or more importantly, admitting that it sucks) is the first step in becoming a better developer. In any case, the same principle for having more and more code is also true for having more and more documentation: More documentation is a symptom of complexity. It's not a feature--it's a liability. So if design patterns themselves don't necessarily mean simplicity, what about Refactoring? Does that solve the problem?
I Code, You Fix It (Later)
Refactoring is certainly one of the best things you can do for your application(s), and it definitely can reduce the coding "footprint" that you impose on developers who will eventually maintain your code. However, at the risk of sparking some controversy, if you're the initial developer, refactoring is actually something that you should avoid, and I'll explain why.
Hold Your Pitchforks...
Before I become labelled as a madman, let's analyze the etymology of the word "refactoring". The Greek/Latin root of the prefix "Re" roughly translates to "again", and the word "factoring" (according to dictionary.com) means:
2. the act or process of separating an equation, formula, cryptogram, etc., into its component parts.
The meaning of the word "factoring" (in this context) is effectively the process of designing your application. In other words, when you combine those two small phrases together into the word "refactoring", it means that your design was faulty enough to warrant a redesign of your code. So my only criticism with refactoring is this--refactoring isn't a preventive measure. It's a reactive measure that everyone (including myself) undertakes when they slowly realize that their code really, really sucks.
So when I say that you should "avoid" refactoring, what I'm actually saying is that you should avoid having to make your code so complicated that it needs to be refactored in the first place. Refactoring, in practice, is an absolute necessity; however, you can avoid refactoring altogether by making your code so simple that it makes refactoring seem ridiculous. For example, when was the last time you had to debug a property getter/setter like:
public int SomeProperty
{
get { return _someProperty; }
set { _someProperty = value; }
}
Dubya-Tee-Eff?
The above example might seem too simplistic--and some people would even scoff at the concept of debugging something so simple--but that's the idea. It's so simple that you don't have to worry about how it works--it just works. You can criticize it all you want for being so simple, but it probably took you less than a second in your mind to make a judgment about it, and move on to something else more useful. In contrast, it naturally takes several hours (or even days, weeks, or months) to solve something more complex. The point here is that having simplicity precludes the need to refactor and (thus) redesign your application, and that something I'll talk about next.
The Best Code Ever Written
The best code that I have ever seen in my life is certainly not my own; however, it's really easy to remember, and you can find it in between the two comment lines below:
No, I haven't gone crazy. You might be saying to yourself that there is no code between those two comment lines. You're right.
The best code ever written is code that doesn't have to be written at all. Ultimately, it's being able to solve a problem without having to resort to writing code in the first place. There's literally no code to maintain, meaning that no poor sap has to cleanup my code in the long run. No suffering, no pain, and no mess. It's simply beautiful.
For those short of this lofty goal of not having to write code (including myself), however, my only advice is this: Simplicity is the ultimate design pattern. If you write it simple the first time, you won't have to worry about refactoring it because you "fudged" it with several other not-so-simple design patterns. You'll be able to rest well knowing that your code won't cause someone else to curse your name at 4am (your local time), and in the end, that is truly sweet indeed.