I shall start with two laws written 40+ years ago about software evolution by Lehman & Bélády:
Being a software engineer, I often emphasize a lot about code quality along with other aspects of application development. A great deal of effort is required for writing clean code. In the early days, I was blissfully ignorant of the damage I was planting for my co-programmers through my code. As a novice in the world of paid(entry level) developer position at LiteBreeze, I was fortunate enough to land a tutelage under master developers. These experts passed their wisdom through scrutinized code reviews. Due to the current packed schedule I am unable to pass this information to others. Hence, I decided to document a few sections. The list only covers selected fundamentals in an easy digestible format.
There’s a famous poem by Zen
To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
Our Project director has always quoted the following sentence:
Three things in life which require practice
Hence to be a good programmer, you require the right mindset, practice & the best apprenticeship. To sum up: Programming is a collection of acquired SKILLS.
Always use intention revealing names – the name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used[1].
A function should only do one thing and that one thing well. Software entities should be open for extension but closed for modifications (aka Open-closed principle[2]).
LiteBreeze employs an agile model for software development. Requirements keep changing and so does the code. Remove unused code/variables which doesn’t affect the application. Apart from shrinking the program size, it avoids the execution of unnecessary functionality. We can always gracefully recover from this deletion using version control software.
Avoid hard coding values, use environment variables instead. This is important as values differ in development, staging and production. Laravel users can take one step further by utilizing configuration caching.
A complex/lengthy IF condition will be difficult for a programmer to comprehend the logic involved in it. Moreover, you are demanding the developer to hold/process all the half-finished thoughts in their head. Simplify long IF conditions with smaller functions which promote easy perception.
Always practice the use of TRY-CATCH-FINALLY blocks for functions which generate unexpected outputs. In this manner, we increase the reliability/robustness of the application.
Most of our applications use a relational database for storage. Always declare a foreign key column explicitly. Indexes on foreign key columns can provide performance benefits for table joins involving the primary and foreign key. If you are tasked with maintenance of an existing project which doesn’t have foreign keys, make sure to index the foreign key columns.
Avoid writing SQL queries inside loops as it exploits the system resources.
If we are using a framework for development, always strive to follow the framework’s convention rather than a custom developer configuration. We use a framework to increase our productivity. By following convention, introducing a new developer versed in the framework can identify/relate the working with ease. Additionally, a future update of the framework won’t hamper the application.
Understand and use HTTP error codes. Use 404 when a page isn’t found. It should not be used when a requested resource(eg: user, post) is not found in the datastore. Rather, when a requested resource is missing, the browser should be redirected to the resource listing page with an appropriate message.
Technical debt pic.twitter.com/w0wDsAN1Mm
— Kent Beck (@KentBeck) October 5, 2018
The image in the tweet paints a very good picture of technical debt. Clean/good code means sustained development. The quality of code today is directly related to the ease of development/extension tomorrow. Each step we take today to write good code provides compounding benefits to the application. Besides, it benefits oneself as a developer by improving our skill set. If the quality of the code isn’t good, future changes become perilous and complicated.
Never duplicate code. If duplicated code requires modification, there’s a danger that one section of the code is updated without checking further for other instances. Duplicate code can be fixed by refactoring it into its own function.
Avoid writing HTML inside Javascript. HTML can be passed to Javascript either by using a variable or by using AJAX calls. This processing method will provide more clarity in separating code and presentation logic. Separation of concerns minimizes time dependency and allows for concurrent development. Moreover, if a change in design is to be carried out, the designer needs to only refer to the HTML templates rather than the Javascript code. Also, this separation promotes readability. It is easier to read business(code) logic that is not intermingled with presentation logic & vice-versa.
Is an abbreviation for You aren’t gonna need it. A programmer should not add functionality until deemed necessary. XP co-founder Ron Jeffries explains it as: Always implement things when you actually need them, never when you just foresee that you need them. Even if you’re totally, totally, totally sure that you’ll need a feature, later on, don’t implement it now. Usually, it’ll turn out either a) you don’t need it after all, or b) what you actually need is quite different from what you foresaw needing earlier[3].
Is an acronym for Keep it simple, stupid. The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided[2].
Premature optimisation happens when a programmer lets performance considerations affect the design of a piece of code[2]. Developers waste enormous amounts of time thinking about the speed/memory usage of their programs. In other words, developers often tend to optimise the code upfront before completing the functionality. Instead, the developers should initially code the program to complete the task. Then make sure to verify the code can be maintained. And finally, address performance[3].
Code is read more often than it is written. Commits shouldn’t contain any debugging codes. Follow coding standards & indentation style relevant to the framework. Hence formatting viz. indentation, line breaks, splitting lengthy conditions all add value to your code.
Communication skills are very valuable for programmers; especially due to the global nature of software projects these days. With English being the universal language, learning functional English and being able to convey your message without spelling mistakes, grammatical errors etc. is a must.
Our Swedish manager always asks us to keep a To-do list. This is done to keep tabs of pending/upcoming tasks. Similarly, when reading Kent Beck’s book about programming, he would jot down the feature requirements as To-do tasks. As a task gets coded, he would mark it as completed. If he finds a new problem which arose while coding the task, he would add it to the To-do tasks. Picking each task one at a time lets you complete the feature in an organised manner. I would suggest the Plain-tasks package for Sublime Text enthusiasts.
Flawless code isn’t always feasible. Nevertheless, we should strive to upskill. All it takes is a little diligence, creativity and adherence to best practices.
References:
Sajith K -
👍