A programmer should take great pride on what she does, coding in a hurry and with a tight deadline often produces unreadable code, it might work, but yikes! who’s gonna be able to maintain it afterwards…Only when you are a zen on identifying code smells you can create beautiful code from the beginning and in a hurry. It takes practice, it’s an art and you don’t become a sensei in a blink.
I think I mentioned before I was embedding myself into the pages of this book:
My programmer’s life has been more fixing someone else’s code than creating code from scratch. No programmer likes to do maintainance, but hey! welcome to real world, code has to be maintained.
I just found this great article on what can be defined as beautiful code. It doesn’t have Fowler’s technical explanations but coming from a mathematician (Matthew Heusser) it’s certainly concise: (taken from the original article at DDJ)
- Beautiful Code is readable. Perhaps nothing is worse than trying to maintain software that does everything yet no one understands. This means that our functions shouldn’t be too long and should accept a reasonable number of variables. What’s “reasonable”? Military science (and chess, for that matter) teaches us that most people can only keep 3-7 variables in our head at the same time. When we get beyond that, we lose track of things, and that means we have forgotten things, which means defects. At that point, it’s time to consider breaking our software into smaller chunks.
- Beautiful Code is Focused. Code should do one thing, and do it well. All the object oriented theory about model-view-controller is essentially an attempt to separate the user interface from the business logic from the back-end system. Mixing these up limits reuse and makes test automation look more and more like fantasyland. I will just say that we should strive for simplicity and generality–to do one thing and do it well. I would submit, however, that this subject is worth researching.
- Beautiful Code is Testable. A well-defined function, given specific input, should have a clear expected output. This makes sense, yet many functions are written with “out of bounds” behaviors that are undefined. For example, consider a function designed to take in a coupon_id and determine if that coupon is valid. You can write the function signature in pseudocode in two different ways:
- Option 1:
- Option 2:
struct eligibility_type(ok boolean, msg string, good_coupon boolean);
sub get_eligibility_of_coupon(coupon_id, optional date assume sysdate)
Assume a coupon_id is an integer. What happens in option 1 when you pass in -1? Or, for that matter, any value that isn’t a valid coupon? Or Null? We don’t know. To test option 1, we need to know some coupons that are valid or not valid as of right now. We probably have to write a query.
For option 2, we can create a list of coupons that are valid as of a certain date, then pass in that date. We can test all kinds of interesting scenarios like “what happens on leap years?” We can provide a different response if the coupon_id was invalid than if the coupon_id was just expired. In short, option 2 is testable. Murphy’s Law applied means that testable code is better code.
- Option 1:
- Beautiful Code is Elegant. I’ve heard it said that the charlatan makes the simple seem hard to understand, and the genius makes the complex easy to understand. Elegant Code (like recursion) shows up when the complex program has a simple solution. When the specification is three pages and the code implementation is one. It’s hard to grasp “elegance”, but we’ve all seen bloated, bug-ridden code that was not elegant. If you’re like me and can’t clearly define elegant, then my suggestion is simple: When coding, remember buggy, junky code, and create software that is the opposite. Elegant code is powerful code… As Antoine de Saint-Exupiry said so eloquently: “Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away.”
Continues on next post…