Have you ever noticed that there are about 1001 ways to do something, especially in software development? As I tell every developer who joins my team, especially interns or junior devs, no one knows everything and every solution should be considered.
I was recently confronted with 1001 ways of doing a task, so I thought it would be a good opportunity for me to explain the different steps I went through to write a little algorithm. The example is quite simple; you might know that in the music industry, new releases are released on Fridays. My task was to retrieve date ranges of releases weeks, therefore from Friday to Thursday — and it could start from any date.
Define your own acceptance criteria
When you’re working on an algorithm, there are two possibilities: you already have the best solution because you’ve worked on something similar before, or you start off with a draft version that you will improve step by step. In this example, I went step by step to find the best way to work on it.
“The best way”. What is ‘the best way’? What does that mean? How can you be confident that your solution will be the best?
The best way means the solution that best matches your own acceptance criteria. After all, there are 1001 ways to do anything. This means that the best solution for you might not be the best one for everyone else. So it is important to define your own criteria.
Your company might have their own criteria, and you may have had different criteria before. More generally, I think that everything that could impact the developer experience may be considered. You might want to focus on the number of lines, semantic, maintainability, performance or some other criterion. Choose the ones that are most relevant to you.
As for me, when I need to develop something, my criteria are almost always the same: scalability, readability and efficiency.
Tune your code to meet your own criteria
Now the criteria are well defined, let’s try to provide a first version of the algorithm. We need to retrieve an array containing all the date ranges (Fridays to Thursdays) from a start date. Even though the deadlines are not so tight, you may need to provide a first draft of the algorithm that works and meets our needs before improving it. This can help you keep a healthy balance between delivering and “pimping”.
array (size=45)
0 =>
array (size=2)
'from' => string '2019-01-04' (length=10)
'to' => string '2019-01-10' (length=10)
1 =>
array (size=2)
'from' => string '2019-01-11' (length=10)
'to' => string '2019-01-17' (length=10)
2 =>
array (size=2)
'from' => string '2019-01-18' (length=10)
'to' => string '2019-01-24' (length=10)
...
First version review
Now the job is done, we need to refer to the criteria previously defined (scalability, readability and efficiency) to check if the code above respect them. Evaluating code can be subjective, in particular with the readability criteria, this is why I suggest you to read multiple times your code before sharing it with other developers to get their feedback.
The example above could be improved, here are the first issues noticed:
- Using a 1-day period loop whereas Fridays come every 7 days (efficiency)
- Too long lines (readability)
- Complexity using int values for both Thursdays and Fridays (readability)
- Complexity using
if/else
condition within aforeach
loop (readability, scalability) - …
You could find many more things to improve in the code above, don’t forget to refer to your criteria.
What about unit testing ?
Before starting to “pimp” the code above, it would be interesting to write down unit tests. They will ensure that all the updates you make don’t break the algorithm. Some of you may be familiar with the Test-Driven Development (TDD) process, which consists in writing unit tests before starting developments. In any case, this is the right time to cover your code with unit tests.
A few versions later…
How did I improve the algorithm? What helped me? What are the steps I went through to get this solution?
I first focused on the efficiency issue so I turned the 1-day loop into a 7-day one. Once done, I handled the nested if/else
condition complexity as I had no idea how to fix the too long lines issue.
Of course, instead of setting the $startDate
in one line, I could have split it into several ones in order to reduce line length. Readability would have been improved. But there must be another way to do so.
After talking about the last issues I had with other developers, they helped me find out the best solution. Exposing them the need and all the solutions I thought about made us more efficient in solving the issue. It is easier to review suggested solutions than to create a new one. Finally, digging deeper into the php doc on date
helped us.
It is important to be surrounded by other developers, whether they are more experienced or not, as we all have different experiences.
The final solution passes the unit test and matches my criteria. The developer experience has been improved and the loop is clear and more efficient. The algorithm is now matching my criteria.
Keep an open mind and update over time
As said above, my criteria are “almost always the same”. Why not always ?
Web development is a sector that changes so quickly that new methods, new objects, new frameworks and even new principles come up very often. Someday, you will meet someone or read an article describing different criteria from yours and they will pique your interest. But do not forget that criteria are something subjective so don’t lose sight of what matters to you and be prepared to defend your point of view while keeping an open mind.
Trends change, and one day a method used in the algorithm above will be replaced by something more efficient. Then it will be no problem to update it because maintainability was part of my criteria.
The thing to keep in mind is that the solution you choose at the moment you choose is the right one because it was the one that matched the criteria you had at the time and you should be proud of it.
As you can see with the issue I had, every step I went through has always returned the same result (ensuring that you are still able to deliver on time). There might be 1001 ways to do something but in the end you have to choose one. Defining your own acceptance criteria and exposing your solution to other developers are the keys to finding a suitable solution.