• Code quality

Practical advices on how to create quality code
for software systems

Introduction

Software developers often think about how to create and release an information system (further mentioned as IS) only. But if the IS is really important for a customer business it can live for years and it could be changed in process, being adopted to changing business logic of a customer.

When you need to implement new requirements in an already released system you will often face next problems:

  1. Changes are quite long and expensive to implement.
  2. There are new errors to appear in a parts of IS that seemed to be untouched by current changes. So, you will need quite costly and long regression testing.
  3. And even after the regression testing is done, there are still some issues which could be fixed for almost indefinitely.
  4. Performance or reliability issues start to appear - slow performance, hangs, losing data, etc.

There could be many reasons for these problems, but one of them is a code quality. In this article I will tell you about some of our approaches to create a code that would let us to minimize chances of facing the above problems.
We should speak only about the code quality and will not mention architecture, development framework choice, quality assurance, project management and other important aspects. Perhaps we will talk about them in the next articles.

Quality code

So, what could be done to improve quality of a team code?

Version Control

As we already know, version control systems are used for code storage, code access for all of the developers, resolving issues with parallel work of several developers and providing the opportunity to rollback unsuccessful changes. Yes, that is all correct. But, as an important addition to this, version control system is a part of an inner system documentation, and quite unique one: it helps to determine when one or another behavior was implemented and why this change was done.

So, we have two main requirements for the working with the version control system:

  1. Sensible commits. Commit must be a complete idea in a code. It should not include unrelated changes to a different functional modules and it should not be too small, committing only some uncompleted change fragments.
  2. Each commit should be pushed with a comment, describing the essence of changes and their reason. It could be a plain text or a link to an issue tracker which contains a complete description of a task, or both. Comment should not be a plain copy of the code changes, because you will see the changes in the version control system anyway. Comment must help the reader to quickly understand what exactly was changed and why.

Easy to read code

The main code quality criteria for us is its understandability. If the system is growing and it is actively used then its code is much more read than written. Often you will need to change the code much later than it was written, and, often too, you will not be the original author of it.

So, how to obtain easy to read code:

  1. All methods (and also variables, properties, classes and other entities) must have readable, meaningful and understandable names. So, when you read the name of a method you should quickly understand it’s purpose. And, of course, the name must match the real method behavior. If the behavior will be altered during the change implementation then the method must be renamed.
  2. Each class should have its own area of responsibility and should realize only operations from it. All other operations should go to another classes.
  3. Each method should do one specific action, if possible, and must not have any side effects.
  4. If the method is too long (usually more than 50-100 lines of code) then it should be split into several shorter methods.
  5. You should avoid too much cohesion between the classes. The more dependencies between classes you have the harder it is to understand system behavior as a whole and the harder it is to implement changes to it.
  6. You should avoid complex syntax constructions if you can use more simple ones.
  7. You should add comments to the most complex places of the algorithm workflow.
  8. All team members must use same code styling rules (formatting, tabs, name convention rules).

Same code styling rules often seem to be unimportant, but, practically, it gives a serious improvement for the team work as a whole. Not needing to “mind-switch” when reading the different parts of the code significantly helps on understanding the code fast. And more, the code styling rules help to avoid insignificant changes in the version control system.

Documentation and Comments

The code must be accompanied with documentation and inner comments. Most companies do have strict requirements to entirely cover all the code with comments and, also, describe in detail the structure and the behavior of the code, up to a single class, in an external accompanying document. From our point of view this pattern is not very reliable, because it leads to too much labor costs and it is often the risk that comments and documentation would differ from each other. As a result, you will need to read the code anyway after you have read the documentation. It is much more productive to concentrate on writing code that is understandable without any specific comments and use comments only in most complex and unevident places of it. And the external accompanying documentation must describe its architecture and behavior on quite a high level instead.

Of course, this is all about the system’s inner code. All external API must be completely described and documented.

Very important and effective variant of a comment is a comment in a version control system, like we told above. This comment is always time bound and change bound, so it never could grow old. So, this comment is never needed to be kept in an actual state, but it always allows to understand who, when and why did a specific change to a system behavior.

Code Quality Control

You never can automatically check how understandable your code really is. The only way to control it is the mutual code review by the developers. Any changes or additions to our code are always reviewed by other team members. This process helps us to complete next tasks:

  1. Detecting the bugs that were not found by developer before the code goes to a test environment in the QA department;
  2. Checking the clarity and styling of the code. If the reviewer can’t clearly understand the code, then the code must be changed;
  3. Making it possible to distribute tasks for each module of a current system between the developers. This can prevent bottlenecks, which usually happen when only one team member has the knowledge of module inner realization.

Code reviewing is done by the members of a project team. At first, this insures knowledge share about a system between the team members. Second, this increases effectiveness of a code review, because, obviously, the reviewer must know what the reviewed code must do and the end purpose of doing it. Otherwise, the reviewer could only find syntax errors, typos or obvious mistakes, but he could not find the flaws with business logic realization. Usually the review is made by a team lead, but the developers review each other’s code too. The code written by a team lead is also reviewed by other developers.

After a review, found errors and flaws are fixed and then code goes to a new review iteration. Functionality implementation is count done and ready for testing only if the last review did not add any issues. It is well known that the sooner you find the error the easier and less costly is to fix it. Making a release to a test environment and getting test reports from QA takes more time than a code review inside a development team. So, fixing the issues by regular code reviews is going significantly faster.

Conclusion

All patterns mentioned above usually work great as a whole. Version control systems and specific code styling rules allows for effectively reviewing and correcting the code, and code reviews help to control understandability and quality of the code. As a result, modifications of a system are usually done faster, and release for the QA department contains less errors. QA department does not take so much time to register and recheck the evident errors and could use more time to test some complex system behavior. And so, as a result of it, the customer gets more quality product.

Based on our rich experience, the implementation of the above-mentioned practices helps several of our systems to work for our customers for years, being regularly expanded and improved according to changing business requirements.