Skip to content

Writing high-quality code

One of the software engineering topics that I find myself discussing quite often in various contexts, from work meetings to job interviews, is that of writing “high-quality” code. And in most cases what emerges from such discussions is that everyone acknowledges this practice as being of primary importance in software development, but things start to get confusing when it comes to precisely define what it means.

I find most explanations unsatisfactory as they tend to be either too language-specific or overly focused on particular aspects of software development, such as design principles and coding practices. Even though those are fundamental to writing good code they can be too far-reaching and not well suited to summarize the quality of a code base.

Usually, software engineers would consider code as being of high quality if it’s written according to “best practices”, if it’s easily readable, maintainable, testable, etc. However, there are several attributes that contribute to the overall quality of a code base and taking them individually (or even at random as it’s often done) doesn’t clearly convey the specific quality they confer to the code.

So, what does writing high quality code mean?

After some research and consideration it appears that all the features generally associated with writing good code contribute to address the following concerns

  • Correctness
  • Clarity
  • Cost-efficiency
Figure 1 – The 3C requirements of high quality code

Writing high-quality code means satisfying these 3 requirements. This definition is more accurate than just using a fuzzy label such as “high-quality”, which can mean different things to different people, yet broad enough as it encompasses all the features that code should have in order to be considered of good quality.

The characteristics that contribute to each of these requirements relate to both structural and behavioral aspects of the code, and some of them are instrumental to satisfying more than one requirement at the same time (hence the overlapping between the 3C in the diagram of Figure 1).

1. Correctness

This requirement determines behavioral characteristics of the code that measure its adherence to functional specifications, its ability to handle exceptional situations and the inability to maliciously manipulate its scope. The following characteristics are key to classify code as being correct

    Validity

    The code must properly implement the functional requirements, which in layman words simply means it must correctly do what it’s supposed to. In theory, this implies that there should be no bugs, whether in the logic or in the implementation. In practice, bug-free code is nearly impossible to achieve for sufficiently complex software systems, so this requirement is generally dependent on the capability of the validation system.

    Reliability

    Handling expected conditions with valid behavior is only a partial achievement for correctness. Unexpected situations and edge cases may occur anytime and the code must be able to handle them without causing incorrect behavior or even severe system failures. This aspect must be approached by design and not as an afterthought.

    Security

    The code must be usable only in a predetermined way without the possibility of exploiting it to perform unintended actions that may be potentially harmful. So even if the code appears to be valid, it’s still incorrect if it’s possible to hijack it to carry out unintended activities.

    2. Clarity

    This requirement determines the structural characteristics that code must have to make working with it easy and straightforward. Code is written for others to use it and therefore should be easy to use correctly and hard to use wrongly. It should also be relatively simple to change and adapt to different operating conditions. Following are the main attributes that make the code clear and straightforward to use.

    Consistency

    The code should follow well defined policies that determine how it should be written. Following a set of common rules gives a clear indication of how to address specific situations and ease the process of understanding intents. These policies are generally meant to deal with the following aspects of the code

    • Structure
    • Implementation
    • Form

    Design principles, language best practices, coding conventions and programming styles are typical examples of such policies. Following them makes the code more coherent and intuitive, increasing its readability and maintainability and lowering the chances of errors.

    Cohesion

    Programmers should not be forced to analyze huge portions of possibly unrelated code in order to understand, use and modify specific functionality. There should be a methodical organization so that it’s immediately clear which part of the code is providing which service. Organizing it into self-contained components having precise and highly focused functional boundaries – also known as modular programming – avoids writing spaghetti code and greatly increases its reusability, extensibility and testability, which are essential features for developing well-designed software systems.

    Simplicity

    Simple and expressive code should always be preferred to complex and complicated code whenever possible because simple things are easy to understand, inexpensive to maintain and very fast to execute. Following Occam’s Razor Principle, implementing the simplest solution in few precise terms leads to optimal and clear code in many cases.

    3. Cost-efficiency

    This requirement relates to characteristics of the code that determine its effectiveness in producing value. Unlike many may think, it is not all about how fast the code runs and how much resources it uses. Rather, it is about how good the code is at delivering the expected value considering the running costs.

    Resiliency

    In industrial applications the highest cost to the business is largely dependent upon the reliability of the system because a failure at any given time may likely cause a loss. Therefore, the code must be highly fault-tolerant and resilient before anything else. Writing reliable code with robust error handling is a necessary step in this direction, though there are other aspects at a more architectural level that make a system resilient (redundancy, load-balancing, diagnostics, etc.).

    Performance

    For many systems the value for the business is primarily determined by the amount of processed information or used resources at any given time. In such scenarios the priority may be low-latency and high-throughput (e.g. trading systems), or low resources consumption (e.g. IoT devices). In these cases the code must be highly optimized for the minimum time/space complexity in order to achieve its maximum cost-efficiency. Such optimizations, however, should never been done at the expenses of resiliency.

    Adaptability

    The survival of modern businesses is highly dependent upon their ability to quickly change to take advantage of new circumstances. For these reasons, code that is highly adaptable will be very cost-effective as it allows following new and more profitable business directions with minimal costs. Writing clear code is a way to greatly reduce the burden of making changes thus increasing its adaptability.

    Measuring the quality of the code

    Once the key characteristics that make high-quality code are determined, metrics should be put in place in order to get a measure of such “quality”. Modern Software Engineering provides many means to quantitatively determine if a code base has been written in accordance with all the criteria.

    Continuous Testing is the modern practice to measure the correctness of a code base. Running the code thru a variety of test stages in the CI/CD pipeline is the only way to verify its validity and security. While testing does not give a 100% guarantee that a software is bug/vulnerability-free it provides useful metrics (such as code coverage, defect density, etc.) that are good indicators of the probability of correctness.

    The clarity of a code base is expressed mostly in its design and implementation stages and the skills of the engineers play a crucial role in this regard. It is undeniable that Software Design skills greatly contribute to clean architectures, so knowledge of the fundamentals of good Software Design is paramount and should be assessed alongside coding skills (sadly this is often not the case).

    Many modern software development platforms provide useful code analysis tools that can calculate metrics such as degree of coupling between components (useful to have a measure of cohesion), cyclomatic complexity (to measure conciseness), maintainability index, LOC, etc. A very important role is played by code reviews, which are the last line of defense against poorly written code and should be a fundamental part of the SDLC.

    Many techniques also exist to measure the performance of the code in order to determine its ability to drive value. For high-performance systems the efficiency is assessed thru profiling, which should be an integral part of the software development pipeline. And several testing methods also exist to measure the resiliency of the code, from unit testing to stress testing, chaos testing and more.

    Conclusions

    Writing high-quality code is certainly not a trivial task as there are several characteristics that determine the value of a code base. All of them, however, contribute to 3 main goals that should be achieved in order for the code to be considered of good quality.

    Undeniably, correctness is the most important requirement and probably also the hardest to achieve. After all, code that’s doing things wrongly or that’s unreliable and exploitable bears little to no utility, no matter how clean and efficient it is.

    On the other hand, code is developed to serve a business scope and to create value. This entails considering the economics aspect of it, that is how it creates value given its running costs. In this regard, writing clear code, no matter for what type of system, is certainly a way to achieve a business goal by reducing the cost of maintenance.

    At the same time, performance, resiliency and adaptability are the biggest determining factors for the efficiency of most systems in terms of cost/benefit ratio, and may be the driving factors in measuring the overall quality of the code compared to other aspects, depending on the application.

    So, regardless of context, we can say that high quality code is code that’s correct, clear and cost-efficient, which summarize the structural and behavioral characteristics it must have in order to allow for industrial-strength use.

    Published inSoftware Engineering