"Building software is more like creating a work of art, it requires creativity in design and ample craftsmanship to complete. Software remains malleable, often illogical, and incomplete forever. Agile software development is based on fundamental changes to what we considered essential to software development ten years ago." - Don Wells
The Art of Coding
Coding is an activity that has parallels with many others, but is also unique. It is similar to many artistic pursuits in that one can speak of beautiful code or ugly code, but unlike art it also has a functional purpose. It is similar to architecture in that one builds something that others will use, and indeed the concept of design patterns crosses over between the two disciplines. However coding is functional while remaining completely abstract, and the ability to automate individual processes that coding supports has more in common with fields such as electrical engineering. The overlap with mathematics and robotics is also strong, but software engineering or coding stands alone amongst these disciplines in the way in which it manages to be at once both abstract and functional.
Computer code is a language of instructions, a language that one might use to give precise instructions to a child incapable of independent thought and lacking in common sense; and yet a child with herculean abilities when it comes to repeating simple operations at speed. Facing errors and problems when coding may make the programmer feel stupid or inadequate, but really it is the computer that is inadequate; as any sufficiently advanced technology should be indistinguishable from magic. Ideally computers would just understand natural language with all it's ambiguity. At the moment they do not, and we are left with logical code that can quickly become painfully complex. Complexity is the project killer, and there are a series of heuristics that can help you manage it.
These heuristics are often referred to as code smells, and there are many of them particularly when we consider object oriented programming. However they start simple enough, and each smell is generally paired with a refactoring that will help address the problem:
- obscure var/method names --> rename
- long method --> extract method
- repetition (duplicated code) --> extract commonality
- nested control flow, e.g. ifs and loops --> extract method
- magic numbers (constants) --> extract constant
Code smells, like design patterns, come with no guarantees; they are simply the distillation of the wisdom of many countless previous programmers' efforts to manage the complexity explosion that ultimately kills most software projects. Perhaps more important than any particular code smell, refactoring or design pattern is the process of reflecting on your code; whether this is in the shower, as you wait for your tests to finish running or in a formal code review meeting.
The challenge, as alluded to above, is that complexity creeps in and the code that was clear to you in the heat of the moment is confusing and convoluted when considered several months hence or by other coders trying to maintain what you have created. There are many techniques to help with code reflection such as "rubber ducking
", where you try to describe what you are about to code, or what you have coded, to some inanimate object on your desk. Often the process of simply describing what you are stuck on is enough to resolve a problem, whether that is in a text post to a coding forum, or out loud to your cat. Being able to describe to a colleague or friend is the next step, and may give you the added bonus of someone else's wisdom, although you can often feel you are imposing on someone else in this fashion. One way to resolve this is instead of programming alone and crying out for help when stuck, is to collaborate on code via pair programming, small group team programming or mutual code reviews. Either which way, the critical skill to develop is the ability to articulate what you want to achieve with your code and the nature of anything that is blocking you.
The ultimate openness about your code is sharing it open source and allowing yourself to receive help from the wisdom of the crowd. Of course just pushing something open source doesn't immediately bring useful feedback, but having your code open source means that it is trivial to share the full details of what you are doing when you want to get that feedback, and you are contributing back to the work of countless thousands of open source programmers who have contributed to the software that now supports our modern computer connected world. Anything you do on a computer relies on the efforts of those programmers, and by making your code open source you are beginning to pay off the debt you have to those coding comrades. Often one hears things like "I'll just clean up my code first", or "yes we're planning open source". Keeping your code closed is the way to guarantee code rot. Unless there's a strong business reason to keep your code close sourced make open sourcing it a default and you'll find yourself reaping the rewards of being able to take advantage of a planet wide coding team.