My professional self turned 2 a couple of months ago, so I decided it was time to look back and reflect on what I’ve learned in these past 2 years. I had the chance to work with brilliant people and to solve challenging problems using a variety of tools. I could start listing specifics like Java, Kafka, Cassandra, Spring, etc. but the knowledge to work with these tools was just the technical aspect of my overall learning. A very important aspect nonetheless, but it’s still just the tip of the iceberg.

There is an entirely different aspect that is just as important. It lays the foundations of how I’m going to apply the specific technical knowledge I’ve accumulated. It’s a “softer” one. It’s the approach to solving problems. If I had to weigh the two, I would say the most important things I learned lie not in the specifics of tools, but, on the contrary - in the general thinking patterns I’ve picked up. Principles like DRY (Don’t repeat yourself) or KISS (Keep it simple, stupid) are a prime example of this. They can be applied to pretty much any software engineering problem and, most of the time, are pretty sound advice.

However, even they are not general enough. There is a crucial prerequisite to them, which is often forgotten - avoid shoehorning yourself between inflexible solutions and rigid expectations about your role. Our goal as software engineers is to deliver value and we would be incapable of doing that if we were working with blinders on. It is beneficial to regularly take a step back and ask ourselves “What is the pattern I am applying here? What is the guideline I am following? Is it the appropriate guideline to follow?”.

In this post, I will list some principles stemming from this prerequisite. I have done my best to internalise them, after seeing those brilliant colleagues I mentioned in the beginning follow them all.

Clearly Communicate Your Intent

Especially in our distributed world, to me this often means to make sure your writing has value. “I’m a software engineer, why would I care about writing?”, you might ask.

I was told once that “software engineers don’t work with computers - they work with people”, whether it’s other software engineers, clients or various stakeholders. Working with people means being able to communicate with them. In a distributed world, writing and documenting your intent is instrumental - whether it’s emails, Jira tickets, Confluence pages, Git commit messages (unless you are an offender and your commit messages are like “hopefully it works now…”).

To this end, I’ve observed that the best communicators don’t focus on specific rules about writing a Jira ticket, for instance (As a, I want to, So that, anyone?). Yes, rules can help and they provide structure. However, they are mostly variations of one core principle - everything you write should have value to the current moment, but it should also retain its value as time goes on. A simple rule of thumb is asking yourself the question “Will this still mean anything to someone reading it 2 months in the future?”.

Don’t Reinvent the Wheel

When approaching a problem, often the best question to ask yourself is not “How do I solve this problem?” It’s “Has this problem already been solved?”

It makes sense for us to go rushing head-first into finding a solution - we are professional problem solvers, after all. However, the problems we are solving should be adding value to the business. If those problems were already solved, we would suffer the opportunity cost of not adding more value by utilising an existing solution and using the extra time to work on something else.

The best engineers I’ve worked with are patient and deliberate. They choose the tools they use very carefully. They take a step back before diving into a problem. They survey the available options to them and evaluate each one. They know when someone else has taken care of the difficult bits and compose their solutions keeping this knowledge in mind. This doesn’t mean they shy away from hard challenges. It simply means they prefer to stand on the shoulders of giants when facing them.

“When a measure becomes a target, it stops being a good measure”

This is a famous generalisation of Goodhart’s Law. It’s pretty intuitive. It makes sense. Unfortunately, it’s easy to forget about it and to start chasing arbitrary measures which were never supposed to be a target. Often times it’s management that falls prey to this. You can see it happen with misguided Scrum (or Agile altogether), when teams race to accumulate as much points as possible, even though points are a measure to help with estimation, not a goal by themselves.

The best engineers I’ve worked with never lost sight of what their target was. They often took a bird’s eye view of the project, the way it was managed and the goals which were pursued. Then, they reassessed the software solutions they were designing - were they solving problems in pursuit of an actual target, or problems related to a phantom target, a measure in disguise?

Only a Sith bad software engineer deals in absolutes

You might have noticed that I was cautious not to list any rules in this post (I hope you don’t make a fuss for using the word “law”…). It was important to me to emphasise the general applicability of everything I described. And also to imply that nothing is set in stone and that there are no rules. Just good practices and suggestions. If there was a rule, it would be to be pragmatic. Principles and guidelines are there to help us find our way, but the right path is always dependent on the context of the problem we’re solving.

It sounds like I’ve plagiarised a fortune cookie (maybe I have?), but we often get sucked in tunnel vision when working on a problem and can inadvertently put up mental walls, which prevent us from finding the best solution. It’s important to remember that what is brilliant in one situation, might be disastrous in a different one. Even blind adherence to principles like DRY can lead us on the wrong path. We should always keep in mind the context of what we’re working on. We should be careful in weighing in our options and we should never be dogmatic.(Is being dogmatic against being dogmatic allowed? My head hurts, I’ll leave this for the philosophers to argue about…)