Tomorrow I turn 40. To some people, this may be a massive life event to celebrate (or commiserate). For me, it’s nothing more than another day. When people ask how I feel about my life I tend to think of the following quote from The Big Bang Theory.
“Just like everyone else’s. Subject to entropy, decay, and eventual death. Thank you for asking.” - Amy Farrah Fowler
While I am a little indifferent to turning 40 it has made me reflect on a few things. I have never taken advice well and I do not suggest you listen to me. But, I will write the things I have learnt in life so far and you can take from it what you will.
Surround yourself with interesting, brilliant people.
This is not groundbreaking advice. To grow as a person you need to surround yourself with people that will push you out of your comfort zone. Work with people that make you think and make you question everything you do. Find mentors and learn from them, ask them even the stupidest of questions. The moment you feel comfortable in a profession or a job then you need to rethink your career or find a new job.
Don’t stop learning.
This doesn’t refer only to being a programmer (or whatever you do as a day job). This means read. Read a lot. Read books. Read the internet. Take advantage of the vast quantity of online learning resources. Appreciate the opportunities and knowledge it provides but mindful it can make anyone an expert.
(Pause for ironic effect given the title of this post).
Do things that make you happy outside of work.
There is a theory that to be good at whatever you do, you need to be doing it 90% of your waking hours. This is not true. The key to staying focused on achieving is to sometimes walk away and do something else. There is a culture in some company’s to expect 70 hour work weeks. This is not productive. While you may be working for a prestigious company, you will not be doing your best work. Developers do not need to be building side projects out of work hours to prove they are excellent at what they do. Have hobby’s, go on holiday and enjoy time with your family.
People come and go.
You will make friends throughout life. Social Media has bred the belief that you have to remain friends for life once you have conversed once. This is rubbish and you may outgrow friendships or they may outgrow you. That’s normal and while some take some getting over don’t look back. Don’t treat others badly or in a way in which you wouldn’t want to be treated yourself. Don’t harbour bad feelings and be open and direct with everyone important in your life.
Be your own person.
Finally, people have opinions and views. The only person whose opinion and views you have to focus on are your own. You will disagree with a lot of people but that’s normal. Be respectful and do not force your views on other people. You can try and educate them but they are their own person as well. We are all the result of the millions of conversations, interactions and experiences that have come before this moment. If you don’t feel good about something then don’t do it. If you wouldn’t say something to someones face then do not write it.
The Single Responsibility Principle is a core element of the SOLID Principles. Wikipedia states that the principle stipulates that
“a class should have only a single responsibility (i.e. changes to only one part of the software’s specification should be able to affect the specification of the class).”
Most developers agree with this approach and structure their code accordingly. Then they create methods in those classes with words like “And” and “Or” in the name. This is a clear code smell that your method is doing too many things. Why structure our classes following SRP and then tool them with confusing methods?
As an example, I have often seen code like
Now I am not interested in showing the actual implementation. What I am showing is that it is common to see a method that does more than one thing. In order for the method to complete it needs to do three discrete steps.
As an aside, by refactoring in this method there is a clear violation of SRP at the class level. FileExists and Download methods should clearly be refactored into a separate class.
This simple refactoring results in two classes that now have a single responsibility. Each method has a single responsibility as well. This improves readability and more importantly makes the methods easier to test. It also makes clear the intent of the methods which reduces the ability for it to cause side effects. Side effects from badly designed methods have lost me countless hours over the years. A final reason to structure your methods in this way relates to reuse. By limiting the methods to a single responsibility you will end up increase reuse significantly as you can chain calls up in various ways that you just can’t when they are grouped together as one method.
To end I will include a quote from Robert C Martin on the subject of SRP
“Gather together the things that change for the same reasons. Separate those things that change for different reasons.”
If you’d like to discuss my thoughts on method design then message me via twitter or email.
“Continuous effort - not strength or intelligence - is the key to unlocking our potential.” - Winston Churchill
Sometimes it helps to have experience.
A developer was having an issue with a SQL query running over a large data set. The query was straightforward and on their machine, it ran on under a second. On a similarly sized data set in the Staging environment, it took 50. That’s quite the difference.
The developer had look at all the obvious things. Reviewed the execution plan and tested the code that executed the query. They talked me through all that they had done and to be honest it was the exact approach I may have taken.
Yet, the one thing that stood out was the fact that the query was running on a new Staging database on Azure. So I suggested that we look at its configuration. Th developer was as surprised as me to see that the database had been restored on a Basic Azure pricing tier. Thus, the amount of DTU’s available for processing the query was limited to 5. We scaled the database up to a standard tier with an increased number of DTU’s that matched Production. Our query now matched the performance expected on running it.
Sometimes when looking at issues it is easy to assume it is the code that is at fault. It’s the most logical. Although I would argue that if you have tests based on specifications your code should rarely be the issue. Many a developer has been tricked by a SQL query that isn’t quite thought through but which works on a sample data set only to fail in production. But, it can be an environment issue or setting or something you would not immediately think of. This is where talking the issue through with someone will save you a lot of time. We stress to our less experienced developers that they should seek help with any issue if they have struggled for more than 15 minutes. Talking the issue through with someone (or a rubber duck) results in a faster solution.
If you’d like to discuss experiences of difficult problems you’ve had to debug message me via twitter or email.
It’s 2017 and many of the partners that I deal with are still exposing their data via FTP. This makes me sad!
That (s)FTP is still a mainstream method of exchanging data demonstrates laziness on both sides of the connection.
From a supplier side, you are saying you do not trust your customers. Or you are saying your system is not designed with collaboration in mind. If trust is an issue and you are generating files for a customer to collect what is different to providing that data via an API endpoint? If you do not want customers accessing your application then you can segment an API. You are running an FTP server so why not use it to make the customer feel enabled?
(s)FTP is not as secure as Https. In the majority of cases that I have used it, (s)FTP is used to get files that are then processed. That means when processing you could suffer undesirable behaviour from the malicious code. You have no way of verifying that what was uploaded to the (s)FTP server has not been tampered with. (You are taking precautions right, I mean you are not storing data straight from an FTP file to your database?!!?) Using a secure, encrypted API endpoint reduces those risks.
From a customer side, why are we putting up with it? I am building modern, fast software. Why should I settle on working with company’s that insist on using such old (40 years) technology? Why should I have to carry the burden of checking a server for updated files? Why would I choose this over a company that provides mechanisms to notify me of changes (webhooks etc)? Why do I want to have to process files? I was exchanging XML back in 2005 and JSON simplifies things even more.
Here is a real example of a company that I deal with. They provide their data as CSV files. When we had the meeting to talk technical details they asked what version of the file I wanted. “Erm, isn’t there only one CSV file format?” You’d think! Turns out that the data is provided to utility company’s. They each insist that their data is formatted in a particular order, same data just different order. This has lead my partner to maintain over 90 versions of the same file. Each version contains the same data in just a different order. Now imagine how easy it would be to do this via an API?
If you have similar frustrations message me via twitter or email to vent.
Code style is like fashion style. It is very opinionated and covers a spectrum of good to bad taste with ease. Ask 10 developers how to name things in code and you will likely get 30 answers.
The main thing to remember, as I often state here, is that you will read code many more times than you write it. So, it figures that if you use well defined and clear names in your code it will make it easier when you come back and read it.
Below are a handful of suggestions that I try to adhere to in my own code and which I guide my team to. I do not suggest this is the perfect approach but I have adjusted it over the years through many projects.
1 - If your language has namespaces, use them to segment your code.
An odd opinion to share first but let me explain. Your variable and object names should be short and descriptive. What they should not do is repeat the namespace. Nor should they be tied to a feature by name or be used to group related objects. I have seen namespaces ignored many times in projects which leads to code like
There is no benefit to prefixing Foo to each class name. Use the namespace functionality of your language to segment and organise your objects.
2 - Names should be as descriptive and short as possible.
A bit of an oxymoron there but bear with me!
So a variety of the above code is very common. Short variable names and abbreviations were very common back before I started. A raft of reasons including memory and screen real estate caused their use. But, this is 2017 and I am typing this on a Full HD screen with 32gb of RAM. So those reasons are no longer valid (in most cases). The trouble with very short or abbreviated names is that it makes reading the code really hard. If you use lots of o, a, j, i type variable names then very soon you won’t be able to determine which relates to what type. There are times that short and abbreviated names make complete sense such as counters in loops or indexes.
At the other end of the spectrum is the really, really, long variable names. I worked with a dev once that was so descriptive you would have to scroll to read the whole variable name. I am not joking! This is only just as bad as short names as it makes the code hard to follow and format. Although you do know what the variable relates to.
So how can we improve the code above? First, we need a short and descriptive name for o. We also need to name our object better.
As per point 1, do not include the namespace in your names. I have added a using directive in the code above. Then I have named the object GmailCalendarFacade. It is clear what the object is and indicates any pattern it is based on. The variable is then a shortened name that clearly states what it is referencing. The approach you take can vary based on the items you are referencing together.
3 - Code should read like prose.
Given we read code so much more than write it, it makes sense to make it as easy to read as possible. So, write your code like you would write a story.
A great test for this is to debug some code with a non-developer. Get a business side colleague to sit and run through your code and see if they can follow it. If you have written it clearly enough that they can then you have well named and maintainable code.
4 - It is OK to negate a condition in a name
Some guides you read state that you should not use names such as IsNot or DoesNot. I do not agree and would say you are still aiming for point 3 above.
When did your favourite author last use != in a book?
5 - Use your languages style guide as a guide
All languages have style guides created, usually by the community. Some guides are more strict than others (yes PEP 8 I am talking about you). These guides will offer specific naming and formatting advice for your language. Sometimes a language has more than one community written guides. Pick one, stick to it and remember that consistency is the key. This is especially true in teams.
I have written this based on my experience on many projects built using .Net, Python and Ruby. I am sure that the advice might not carry over to some languages. Functional languages especially put in place different naming conventions. These may recommend shorter more math base naming conventions. The important thing is to ensure your code is clear and concise and following an agreed standard.
If you’d like to discuss my thoughts here then message me via twitter or email.