It’s been around a decade since I first started getting paid specifically to write software. It seems a reasonable time to look back and speculate about the things that i’ve realised over that time.
One person’s personal revelations almost never correspond to anyone else’s and so perhaps most of these things will seem completely obvious. Equally, it is often difficult to distinguish something insightful that just happens to immediately make sense from something that is completely obvious and unremarkable. Hopefully then there’ll be some nuggets of wisdom in amongst what is possibly going to be a series of small semi coherent rants.
There are a number of assumptions that I had started out with regarding software development that wasn’t aware i’d made and that have turned out to be completely wrong. I’m going to try to mention those here together with some assumptions I see others make that just disappoint me or make me really annoyed. None of these are necessarily original or my own invention.
1. You should find one language and master it
As with many of the points i want to make, this is fairly well covered in the pragmatic programmer book. You should aim to learn at least one new programming language a year. One language is definitely not going to work for you – web development means that you will at least need to know one language such as java, scala, c#, php, ruby, python or perl but also be familiar with some of sql, javascript. That and all the ‘frameworks’ that exist on top of those languages you need to understand such as rails, struts, wicket, lift, spring, django, hibernate, seam, asp.net mvc, jquery, prototype etc. You will be useless as a developer until you have passing familiarity with a lot of these things.
I find it very odd that the various communities that surround these technologies are often quite insular. These various communities have a great deal in common and are all trying to solve similar problems. It just doesn’t make sense that in particular that developers involved in more ‘enterprise’ platforms such as .net or j2ee have so little communication. This also applies to the dynamic language communities (ruby/perl/python) vs the same ‘enterprise’ platform developers.
2. You should receive paid training to learn anything new
This is always just offensive and absurd but I encounter it all the time. If you aren’t familiar with something – mobile application development, web development – go out and read some books, some blogs, attend some user group meetings. It is no one’s problem but your own if you don’t know about the technologies you’re paid to use.
3. You should write ‘chameleonic’ code
This is straight out of pragmatic programmer – the notion of ‘broken windows’. Despite understanding this, I had the false belief that when code is particularly incomprehensible the worst thing you can do is put some code that makes sense in the middle somewhere. Instead I thought you should write code that is consistently awful until you have to opportunity to completely rewrite everything.
Legacy code is difficult. Read the Michael Feathers book for some ideas but ultimately the time to rewrite the entire application from scratch probably will never come. Making small improvements over time will certainly make the code seem less consistent but at least starts sending the message that it is worth improving. Talk to each other before trying to introduce radically new approaches, patterns or whatever as everyone must understand the technical direction the code is taking.
4. Comments and documentation are really useful
Comments are a lazy way to indicate when you couldn’t think of a better way to express something in code. I find TODOs especially irksome. If you have gone to the trouble of working out how to improve something why don’t YOU fix it? Sometimes these fixes might take a lot of time – if that is the case, write it down as a task that can be given attention and priority rather than just a self righteous comment buried in the code.
Documentation unless autogenerated or executable is most often misleading and WET (waste of everyone’s time). No one could really be surprised by this – unless by heroic vigilance, documentation very quickly falls out of date and becomes nothing but a source of confusion and misinformation.
5. Greenfield projects are more interesting than dealing with legacy code
It is so much harder to deal with an existing system that I’ve now realised that it is the main challenge of software development. Very few of your projects will be from a blank slate so stop complaining about legacy code and just get better at working with it.
I feel mostly when I am working on a greenfields project that i’m primarily just producing legacy code. You know your sticking to the ’simplest thing that can possibly work’ will not accommodate future changes and can hear future developers bitching about the crappy code you’re now writing.
6. Writing software is about telling computers what to do
Computers will do whatever you tell them unless what you tell them doesn’t make any sense. Computers can make sense out of almost anything so that’s not much of a safeguard.
Software development is about communicating with other developers. That means both the developers you’re working with at that time and also all the developers that will ever work on your system. Make the software make sense to humans or those humans will hate you and try to destroy you.
7. Testing is something someone else does for you once you’ve written some code
Write. The. Tests. First.
Just do it. It is hard. Don’t let anyone tell you it isn’t. It is hard because normally you wouldn’t be forced to work out what you actually want to do. You would just storm in, all guns blazing and write some awesome code that does some stuff. What that stuff is you’ll find out eventually. Most of the time you’ll be disappointed and a little embarrassed as it will not do some of what it should and a lot of stuff you didn’t intend.
When you write tests, you’ll know when you’re finished and you’ll know that it works. It is incredibly important to see that your test fails first. You then write some code. Then you see your test pass. Rinse. Repeat.
You can then safely refactor. Refactoring will ultimately reduce the number of people in the world who hate you.
Write the outermost acceptance tests first so you know the lower level functionality is actually necessary. Do not start writing unit tests for some class that may be completely unnecessary.
There’s nothing new here but it is amazing how many people say they believe this and then don’t actually ever do it.
8. Testing is easy work for less competent people
Testers are strange and gifted people. Great testers will break your system in ways you never thought possible. That doesn’t happen by mindlessly keyboard mashing until something bursts into flames – it involves consideration and exploration.
To show respect for these gifted people who will ultimately save you from a humiliating career suicide if your bugs get out into the real world, you should work with them to automate everything that can possibly be automated. Making intelligent people follow reams of lists of manual tests such as ‘type “giblet” in the search field’, ’click on the “search” button’ is unprofessional, disrespectful and will only lead to workplace gun play.
9. Email is an excellent way to keep track of people’s commitment to decisions
I’ve worked on plenty of projects where rather than talking, people find it more reassuring to conduct all communication via email. This gives them the false sense that there is a trail of evidence in case some project disaster takes place. Because everyone is aware of this – that each communication goes down on their permanent record – no one really has much incentive to commit to anything or to be completely clear.
The solution is simple: talk.
10. Agile software development is good in some limited situations
I’ve been at ThoughtWorks since the start of 2007. Before that I’d read a lot about agile software development but really hadn’t had the opportunity to put it into practice. That’s a real shame as not one project I can think of would not have been far better off following an agile approach.
For some reason, the term agile has a bad reputation. It is easily ridiculed I suppose – people can make jokes about being bendy or dexterous. From my point of view, agile projects are the only ones that admit that no one really has any idea of what they’re doing. Not only is it unclear what the system needs to do but also it isn’t completely clear how the team should work together. So you apply a few basic principles, follow some sensible practices and just cautiously evolve your team just as you evolve your software.
Stop pretending you know everything at the start. You don’t know what will change, you don’t know what the people you have are best at or how they will most effectively work together. People will always surprise you. You will need to set yourself up to make the most of those surprises.
11. Agile software development isn’t rigorous enough
This is just crap. If you’ve ever said this then just punch yourself in the face right now.
Generating charts based on made up metrics and speculation is not rigor – it is waste. Generating charts that plot actual functionality against time is not crap – it is simply fact. To take this further, deploy every successful piece of functionality straight into production. The charts will become very easy to draw in this scenario.
12. You should always buy before you build
Products can be awesome. I’d have to be in a pretty dire situation if i thought it was a good idea to write my own database server, http server or operating system. I am a software developer but I don’t believe that I am the only competent software developer. Almost all software products will have been written by people with similar or superior development skills.
The problem with buying a product isn’t that it is not well implemented. It’s that it doesn’t do what you want. If you are not prepared to change what you want to more closely coincide with what the product does then you are in for a world of pain.
Here’s a lame metaphor that I just can’t let go: say I want to get from Sydney to Perth, could get a direct flight but that might be expensive, instead I get a much cheaper flight that takes me to Darwin. It turns out that the flight from Darwin to Perth costs three times as much as a direct flight from Sydney to Perth. The solution is to enjoy staying in Adelaide. OK – perhaps i’ll hold off the metaphors for the remaining rantlets.
13. A programming language is about syntax and tools
This one seems to come up a lot. Nothing is safe in this industry. Some bastard has a better idea for a programming language, all the cool kids start using it and suddenly you’re all alone managing 1,000,000 lines of java. So how do you choose a winner? You can’t
Surely because eclipse and netbeans are great IDEs and java 7 might have closures we’re safe aren’t we? Not really
The strongest indication is the sort of community that surrounds a language, the associated frameworks and open source contributions. Java has a great history in this respect which suggests that it (or at the very least the JVM) will be around for a long time. .NET on the other hand is newer to this game. Sites like codeplex and the presence of alt.net groups is a very healthy sign. The best indication for me is user group attendance. People who are keen enough about a language community to attend regular user group meetings and present at conferences are likely to be interested in investing in the community.
14. Women do analysis, testing and database administration. Men write code
This should be the biggest rant – it drives me crazy. The alpha geek phenomena in software development is by far the most shameful aspect of the craft.
I have actually had people say to me that they sincerely believe that women do not write code as well as men. Why? How does this make any sense? Kill yourselves now. You might think you are a great developer but your misogyny and arrogance are destroying an industry that desperately needs more proportionate representation of the population.
15. Open source software is written by dirty dope-smoking hippies
Maybe no one really does believe this. I’ve worked on projects where we had to use some hideous and overwrought product just because supposedly a manager somewhere in the stratosphere thought it was a bad idea not to buy something. Perhaps there was no such manager – just a middle level manager that assumed that such a manager existed further up the food chain.
Regardless, it makes no sense. You have as much chance of apache httpd, tomcat, mysql, postgres falling to pieces as you do oracle, sap, jdedwards or peoplesoft. Even if they did, you’d have the source code.
16. You can control change by meticulous planning
This is probably just the same agile rant. You cannot control change – you can only manage it. Prepare for it by identifying the things that you suspect might go wrong, guess their likelihood and have an idea of what your reaction might be if it does come to pass. Controlling change is just burying your head in the sand and needlessly restricting people from getting things done.
17. You should try to use the same technology at every layer of your application
This relates to the very first point. The best example is that if you write web applications you should learn javascript. Not cutting and pasting chunks of javascript from tutorial sites, actually learning javascript.
Generating javascript using java, scala, ruby or whatever is just lame. Eventually you will encounter something that can’t be generated by the tools and you’ll have to understand javascript anyway. Javascript is beautiful. Learn to love javascript
I extend this to testing. Just because your writing a web application using C# does not mean that you shouldn’t consider using awesome tools like mechanize, selenium and cucumber to write your tests in ruby. If nothing else, when you look at some code, you’ll immediately be able to tell what layer of the system you’re dealing with.
18. Anything remotely good can happen for anyone after fixing price, scope and date
Pretty basic stuff. If you can completely ensure nothing at all will alter the likelyhood of your project succeeding then go right ahead. What is the point of your project then if there is no risk at all?
19. You need to be loud to be influential
More whining about alpha geeks I suppose. I’m a shy quiet kind of guy. I don’t want to ever have to yell or shout to make my point. If you yell or shout, you have not convinced me or anyone else to take your point of view.
If you have a good idea, people will naturally adopt it. If they don’t then perhaps it wasn’t so awesome after all or perhaps you need to find a more effective way to communicate the idea.
20. You need to choose to be a project manager or an architect for when you grow up
I really really like software development. There’s nothing like the satisfaction of creating something that actually works.
So I resent this notion that at some point, I need to grow up and completely lose my grasp of low level technology. I’m not interested in managing people – people are scary. I simply want to continue to improve and most importantly to share my experience with other like minded people.
21. There’s something special about large organisations
The only thing special about large organisations is that they are large. The size of an organisation
22. Code can not be beautiful
Everyone should get to experience the joy of working on a piece of code for a while that really just doesn’t make sense. By moving things around, teasing things apart gradually the mist begins to settle. After a while of this, all of a sudden, from the chaos emerges this brilliant shining jewel of clarity. Shielding your eyes from the painful intensity, tears streaming down your face, you commit your changes to the source repository and struggle to get on with the rest of your life.
You image other developers unwittingly opening the file. They think that this is just another normal day. It’s going to be yet another bit of source code that they need to decipher. As the text editor opens, before they can get protective eyewear on their face, the ingeniousness of your source code streams out at them. Their face is mildly scorched but they know they have seen true beauty and their lives with never be the same again.
23. Anything remotely important can be gained by static typing
24. Learning ‘old’ languages is pointless
25. Learning theoretical computer science is pointless
26. You should design your system by starting with a relational database schema
We have too long been enslaved to the relational database. This is strange. Databases can be a good place to put things. Clever people have worked out how to make them fast at getting those things out again quite quickly. Then people suddenly started waving rule books around about how we must normalise our schemas to 3rd normal form. Then sometimes we should denormalise in order to achieve gains in efficency. The rules sometimes say very foolish things such as that we must only talk to the database using stored procedures – that anything else is less secure and inefficient.
Sometimes, you can store data in these things called files. Some data can even be stored in memory or big distributed hash maps. Sometimes people like to store data in directory servers. Some data is is just better to leave with Jeff because Jeff is a good guy.
So when you next assume you need a relational database. Think again.
27. CASE tools are eventually going to be really useful
Most modern IDEs are designed to make generating code easier. This is because writing code is really hard so the only practical alternative is to have software write software for you. You don’t know what you’re doing so you need tools that turn the pretty diagrams you understand into source code that you can’t.
The worst culprit is Visual Studio – within seconds of starting a new project, visual studio can have written thousands of lines of code for you – web service implementations, web service clients, entire data persistance layers flash past the screen into your source control system.
28. Design patterns are crucial and you should use them everywhere
Design patterns are very interesting to read about and discuss. It is great to stand at a whiteboard and talk about classes collaborating with other classes in a way that makes sense. Especially if this is a way that the business stakeholders standing around can almost get their heads around.
What is not interesting is a design pattern trivia wankfest. There are few conversations more pointless than those that take place after an agreement has been reached about a particular technical direction that involves deciding which design pattern words to use to describe it. Is it a bridge, a proxy, an adapter? Is it a flyweight perhaps?
Understanding the concepts of design patterns is valuable but please stop writing software by gluing design patterns together and pretend you’ve produced a system.