I have been a software developer for over 25 years. During that time I have worked on all manner of projects, on all sorts of platforms, with clients big and small. I have worked alone, within teams, and even been parachuted into mentor third party teams.

I thought it might be useful to share some of the lessons I have learned along the way - to help give new developers a little direction, and to avoid some of the most common pitfalls.

Understand requirements

Most software is written in response to a real-world requirement. It's easy to read proposed requirements and interpret them in terms of existing knowledge. While working through potential solutions, it's worth taking a step back - to do some discovery work around the capabilities needed in the solution and to make sure your proposals satisfy the requirements.

Remember - if you're writing software, it's invariably because a search for commercial off-the-shelf software has already come up short. Many projects settle for off the shelf software because it's "close enough" - the requirements can be changed to meet the capabilities of the software. If you're being invited to propose a bespoke solution, the requirements become more important.

Plan ahead

I'm often reminded of a saying I once heard - "measure twice, cut once". Don't start coding a vastly complex solution until you have broken down what each element of the solution will need to do, how well it will need to perform, how it will integrate with other elements, and so on. Draw entity diagrams, talk the design through with your peers and get second opinions. Defend your choices, but also take advantage of the skills and experience of others.

Code with style

If you have never worked in a team with other developers, I cannot emphasise enough how important it is to write clean, tidy code. There are very few excuses with modern development environments, which bristle with features to assist in code-layout and presentation. The internet is also full of open source projects that can be reviewed.

Follow agreed styles - do not read an article and decide to change the way you code (unless you're working on your own).

Source code should be consistent, and readable. Where possible break large swathes of code down - use class libraries, functions, and namespaces to separate concerns. Keep the purpose of functions discrete - it will make testing easier.

Comment, comment, comment

Commenting your code should be a given - you're probably going to need to look at it again in six months - maybe several years from now. Guide the reader through more complex functions - preceding anything complex with a simple sentence explaining what's going on. Don't force the reader to interpret your source code.

To help other developers who may never have worked on your project, precede every function with a short summary of what the function does, what it's parameters are, and what it returns. Most integrated development environments will have shortcuts to help you do this.

Do not go mad - simple code should be self-explanatory, and well-written code doesn't require hundreds of comments to follow.

Keep it simple

The most common reason to complicate code is to chase performance - so weigh the need for it against more elegant code that works well enough. This is a double-edged sword - while the purists will always want to write the most performant code, it has to be weighed against the time required to understand and manage the code going forwards - the fastest solutions are often less obvious, and more difficult to maintain.

It goes without saying that simple code is easier to test too.

Do not re-invent the wheel

It pays to know the programming language you are using - put some work into learning what toys are in the box. As an example, both JavaScript and C# have evolved tremendously in recent years - allowing for more succinct coding patterns. Where previously it might have been somewhat complex to perform functions such as walking through filtered and sorted collections of objects, language improvements have made such tasks trivial.

If you need to perform any common integration function - such as sending email, communicating with a database, or talking to a web server, use a programming library. Don't waste your time re-inventing the wheel if another developer has already done all the hard work for you. However - also be mindful of the scope of third party libraries. I've lost count of the number of times I've seen jQuery added to web projects for one or two calls that could easily have been written in plain JavaScript.

Document Everything

For anything but the smallest projects, it pays to have documentation - both to record your thinking during design and development, and for others to refer to when coming into a project. One of the huge fallacies associated with agile development is that the developers can just start coding, and figure things out as they go - this almost always leads to disaster.

Drawing diagrams and writing notes helps frame your thoughts. Thinking about the bigger picture while not surrounded by source code helps enormously. Thankfully the widespread availability of wireframing and more general diagramming tools makes the sharing and publication of documentation a breeze too.

Pay your Code Tax

Nobody is perfect - you will realise there were better ways of doing things half-way through the development of a project. If in doubt, always re-design or re-write code rather than patch it.

This can often be where up-front planning pays off - if you have gone as far as writing an API specification, it really doesn't matter to anybody else how you achieve the results for particular functions or calls. If you take shortcuts to implement functionality, you will always know what you did. It will be on your conscience.

We can't always strive for perfection - commercial projects have budget and time limits associated with them - sometimes you will have to fall on your sword and solve something the quick way, rather than the proper way. In such situations, it's always best to be transparent, and communicate what you are doing, and why.

Push Commits for a Reason

During development, most developers check their code into a source code repository at the end of every day. This is fine - it safeguards your work, and the commits tell the story of how the project was built.

After release, pushes of commits to master branches should be atomic in terms of the issues they resolve. Do not muddle up issues, features, and commits - you will pay for it with cascading failures while trying to unwind one issue that caused another.

Discrete commits also help with testing - allowing bugs to be narrowed down to a specific change in the source code, and a specific commit satisfying particular intentions.

Stay humble

No matter how clever you think you are, others will think of better ways of doing things. No matter how fast you think you are, others will be faster. Here's the thing - it's not a competition.

I sometimes watch "competitive programmers" solving problems on YouTube and can't help laughing. Yes, they are fast, and yes, their solutions are often quite elegant, but they are also unreadable, uncommented, undocumented, and unmanageable.

I've worked with some incredible programmers over the years. I used them to my advantage - if I couldn't figure out how to approach a problem after headbutting the desk for a while, I would make a coffee and go visit their desk. You tend to find that software developers love solving problems.

It's not about you

Software development is never really about how good you are at programming (although it helps a lot) - it's more about understanding requirements, communicating well, having a great work ethic, being relatively pedantic, and above all being thorough.

Of course, if you are also able to write clean, fast, efficient code, that's going to help a lot too.