DEV Community

Cover image for Beyond Bugs: The Hidden Impact of Code Quality (Part 1) 🌟
Rowan Ibrahem
Rowan Ibrahem

Posted on

Beyond Bugs: The Hidden Impact of Code Quality (Part 1) 🌟

🔴 Introduction
As software engineers, we often encounter unexpected bugs or delays when adding or modifying features that should not occur. Most software engineers focus on finishing the product to deliver it, but did you think about your code quality? Imagine constructing a building on a weak foundation. Adding just one more floor could cause the entire structure to collapse.

Similarly, poor code quality can lead to software instability and make adding features easier. Today we will see the hidden importance of code quality and how we develop good software.🧐

Image description

🟢 Table of contents

  • What is Code quality?
  • Why it’s important?
  • Code Quality standards.
  • Factors of Code Quality.
  • Tools to measure Code Quality.
  • Tips for Improving Code Quality.
  • Conclusion.

What is code quality?🤔
There is Lehaman’s low say:
“Any system that’s used will need to change”.
That means that you will need to change and update your code every time.

Imagine that you don’t care about your code quality, so you won’t be able to change your systems without difficulty or many bugs.

So Code Quality is the desire to create code that is easy to understand and maintain.

We can say that is a way to measure the efficiency, readability, and usability of the code. We can know the quality by measuring the accuracy and reliability of code and how can it be easy to maintain and read by other developers.

Why it’s important? 👀
There are a few things you shouldn’t rely on:
Future availability - Future memory

Imagine this scenario: You start a project and say that you will enhance it later but then you get busy and another team will complete the project, so you should ask yourself, Are they will be able to read and maintain it easily? What happens when they add more features? How will that impact the performance and bugs?
Code quality helps the developer re-read and redesign the code.

By Measuring the Quality of the code we become sure that the end-user will have an enjoyable experience.

It helps in Reducing future errors, producing good performance, easy to maintain in the future, easy to know the bugs early, and having good security.

It’s important to remember that every time someone changes the code, there’s a risk of it becoming less organized.
When software lasts for a long time with few errors, it can save a
company money. Instead of paying for additional time to rewrite.

Image description

✅What are code quality standards?
There are many factors called standards to ensure code quality.
The main roles of Code Quality are readability, clarity, reliability, security, modularity, etc...
These qualities make the code easy to understand, change, operate, and debug. Let’s take a thorough analysis of them.

Factors of Code Quality ⁉️
Maintaining high code quality is essential for developing software that is efficient, maintainable, and scalable. To achieve this, there are several standards and tools available to measure and improve code quality. Let's dive into these standards🤩

1-Complexity
Complexity measures the difficulty of the program or code as we know in the algorithm with Big O, so it’s a measurement of how code is easy to understand and maintain.
Some factors affect the complexity such as lines of code, loops, and conditions.
The recursion function is a simple example of how the code is complex to understand and affect the memory.

So, Why we should enhance it? 🤔
If the code is less complex, it makes high-quality performance
rather than it affects the resources such as the memory or CPU, and becomes difficult to add new features without negative performance to the project, maybe it will increase the cost of the project.
We have types to measure complexity:
Cyclomatic Complexity - Structural Complexity- Algorithmic Complexity - Cognitive Complexity.🌟

Let’s take a Simple example
Cyclomatic Complexity:
It is like counting the number of different routes you can take through a city to get from one point to another.
So, in a piece of code, these "routes" are determined by decisions or branches, such as if statements, loops (for, while), and switch cases.

Image description

The complexity here is 3 as we have 3 routes :

  • The order is paid.
  • Order in stock.
  • The order isn’t paid.

Cognitive Complexity:
means that humans can understand and read it easily.

Image description

Here you will find it difficult to understand it from the first time

We can refactor it to make it more readable with the least nested loops and easy to understand like this :

Image description

There are other ways to measure complexity, you can take a look here for more details :
https://blog.codacy.com/code-complexity

2- Hotspots and churns
It’s like, What’s your coding hiding?🕵🏻‍♀️
Hotspots are parts of the file or the code that are frequently modified to update, add features, or fix bugs.

They may contain complex code and may cause bugs or require maintenance.
They consume the most resources, like CPU or memory, this is why we need to optimize hotspots to improve performance.
We prioritize them to know which parts need to be maintained.

Churnscount the number of times a file changes, including code that developers added, modified, or deleted within a codebase over a specific period.

So, how can we know these files?
Version system controls like Git&GitHub track every change in all files they produce a history of file changes so you can know which files changed frequently.
You can find it in the GitHub Repo and see the history of commits.
The file that changes a lot has high churns and will be hotspots that need to improve.
We should care about it as if the file knows that it is file changed a lot and has a high complex, it may cause big errors when trying to maintain it.

Image description

3- Reliability
This ensures that every function efficiently does its job and if there are unexpected errors, the system will deal with it sufficiently without any crashes. That is why we make error handling.
To ensure that our system is reliable, we can make unit tests for our function to ensure that everything works well.

We can use debugging and profiling to ensure that our code is efficient.

At the end of the project, the tester makes an automation test to be sure that the system can deal with any crashes and will not affect the user experience.

If we know how many times the system fails in some period, we will know the reliability of it.

4- Code coverage
How good is your test suite?
Code Coverage is a metric to measure the percentage of automated tests to execute how much of your codebase.
It indicates the test cases you’ve written have tested how much of your code, helping you understand which parts of your code are well-tested and which parts may need more testing.

It produces a percentage of acceptance of the project that we can deliver software or it still needs maintenance based on these tests (unit test -integration test - acceptance test ).

There are many types of code coverage you can see in more detail here :
https://www.browserstack.com/guide/code-coverage-vs-test-coverage

5- Maintainability
Sometimes we need to modify, update, or extend the system over time to meet new requirements, so the system should be flexible and able to expand without causing any problems.

We can make it maintainable in many ways :

  • Code refactoring to eliminate any duplications and make it clear.
  • Documentation: Good documentation provides an overview of the system, how it’s structured, and how different parts interact. It includes code comments, design documents, API documentation, and user manuals. Documentation helps developers quickly get up to speed with the system and understand the implications of their changes.
  • Encapsulation and Abstraction: we can make Encapsulation (hiding implementation details) and abstraction (focusing on high-level operations)these concepts in OOP keep changes localized. This minimizes the risk of unintended side effects when the software is modified.
  • Modularity divides the software into distinct, independent modules or components. Developers can develop, test, and modify each module separately, reducing the impact of changes on the entire system.

Let’s see an example:

Image description

Here the function is made more than one job if I want to add or remove an update it will crash

Image description

Here, if I want to add or remove an update, the function performs more than one job and it will crash.
Here is a modular code that separates the different tasks (validation, payment processing, inventory update) into distinct methods. This separation makes the code easier to maintain because each method is responsible for a single task. If you need to change the payment process, for example, you only need to update the process payment method.
This makes the software easy to maintain and makes developers contribute easily and improve the performance of the software.

6- Testability
As we mentioned, there are 3 levels of testing (unit test - integration test - Acceptance test) so testability means how easily and effectively you can test a piece of code or a system to ensure it works as expected.
We should ensure that we test our code thoroughly to verify the proper functioning of every function, eliminating any potential errors or bugs in the future, thereby enhancing the user experience and facilitating ease of maintenance.

7- Readability
As your handwriting should be clear so that people can read it, your code also should be clear and readable for any developer who reads it.

How can we make our code readable?

  • Clear naming conventions: you should write descriptive names for classes, variables, and functions that express their objectives.
  • Modularity: make code smaller and modular in functions and classes. This will make code easy to maintain and debug.
  • Coding style: follow code style in indentation and formatting, make comments to be more easy.
  • Code structure: follow clear architecture and pattern in your files
  • Avoid any hard coding and don’t forget to make error handling.

Example:

Image description

If you look here, you will not be able to understand what a or s
You don’t know what is the purpose of function and it’s one method in the main.

Image description

Here you can find it named more descriptive. We break the method into small methods.
Also, we add comments that make the code easier and formatted well.
So you should make your code self-documented and refactor it as you can.

8- Reusability
Like a sault in our food, we can put it on different types of food, Our code should be reusable so that we can reuse it in another component or another project without causing errors.

How can we ensure from that?

  • Make your functions and classes into small blocks to be sure that they are reliable and not dependent on another component.
  • Avoid repetition: if you find that you write the same code twice, you should reuse it to make it once and use it anywhere.
  • Following SOLID principles will help you.
  • Encapsulation and abstraction make reading easier as they make the modules independent.
  • Use the Loose Coupling principle that minimizes dependencies between modules.

Example:
Imagine you need to create three different buttons on your project, one on the login page, one on the signup page, and one on the contact page. You might write something like this:

Image description

Here, you've repeated the button code three times, just changing the text and color. If you later decide to change the padding or font size, you'd have to find and update every button manually.

With Reusability:
Instead, you can create a reusable button component in your code

Image description

Then, use this component in different places with different colors and text:

Image description

See, that saves time and effort when we want to change something, we will change it once.

9- Portability
Software can run on different platforms, operating systems, or environments with minimal or no modification.
The system should work in different OS like Windows, Linux, and macOS.

It should run on different browsers without any bugs or crashes.
If we make an application, it should be flexible to run on different versions of Android or iOS.
The product enhances efficiency and is compatible with a wide range of customers; otherwise, you will have to create different codes for each specific environment.

10- Performance
The most important factor in code quality is performance.
We do all maintenance and code quality to measure our software's performance because if our software's performance is high, we can say that we make good software and products.

So performance is how efficiently our code is organized and optimized.
We can measure it from speed, responsiveness, and resource usage.
High performance means that the software operates quickly and effectively, using minimal resources like CPU, memory, and network bandwidth.

Examples of bad practices that lead to low performance:

  • Uncompressed images, wrong sizes of images, wrong format of images.
  • Including whole libraries when they can be tree-shaken to a fraction of the size.
  • Loading everything synchronously when it isn’t needed on a page.
  • Not utilizing browser cache.
  • Unused packages or images.

Every technology and framework has its ways of improving performance you just need to search with “How to improve Performance in …”.

11- Duplication
How much do you repeat yourself?
There is a DRY Principle that says you shouldn’t repeat yourself. Some developers take the code copy and paste if there are two components with the same code, but this very bad practice leads to many problems:

  • It reduces the performance of the product
  • Will cause a big maintenance effort
  • When you don’t update the duplicated code consistently, it may lead to great risk errors, causing different parts of your application to behave differently even though they were intended to be the same.

12- Security and dependencies
The most important part of releasing your product is to ensure that it is secure from attacks, so security is to follow guidelines and principles to protect your code and data from any attack or unauthorized access.
Dependencies Management Security: dependencies should update every time to prevent attacks.
Your system can face problems if you don’t use a reliable library or framework.

To ensure that your application is secure, you should take care of these things :

  • Input validation: you should ensure that input data is valid to prevent SQL injection or cross-site scripting
  • Authentication and authorization: you should implement a strong mechanism to control access. I recommend using Key cloak technology as it has high security in authentication
  • Data Protection: you should encrypt sensitive data by using techniques such as encryption and secure storage
  • Secure coding practices: follow secure coding guidelines and standards (e.g., OWASP, SEI CERT) to prevent common security flaws.
  • Security Testing: Conduct regular security testing, including static code analysis, dynamic analysis, penetration testing, and vulnerability scanning, to identify and fix security issues.

Security is important because if happens any attack it will lead to a loss of importance and loss of trust in a client, which will cause financial problems for the company.

13- Code Style
How clean is your code?
A coding style is a set of guidelines on how to format code. For instance, what do you call your variables? Do you use spaces or tabs for indentation? Where do you put comments? It gives your code the same style and is enjoyable to read, especially when working in a team.

There are style guidelines for each language, but overall, most languages use liners and most Ides support auto-formatting.
For commonly used style guides for various programming languages, see the Language Guides. Google also has a style guide for many languages that are used in open-source projects originating out of Google.

The coding style is made up of numerous small decisions based on the language:

  • How and when to use comments,
  • Tabs or spaces for indentation (and how many spaces),
  • Appropriate use of white space,
  • Proper naming of variables and functions
  • Code grouping an organization
  • Patterns to be used,
  • Patterns to be avoided.

Example

Image description

Good Version

Image description

Indentation ensures a clear structure by properly indenting each block of code.
Spacing: There should be spaces around operators (+, =) and between method parameters for better readability.
Line Breaks: Each statement is on its line, making the code easier to follow.
Method Naming: Using more descriptive method names (such as addNumbers, printResult) is a good start, but you can further improve them by being more specific (for example, by using calculateSum and displayResult).
Comments: Added comments describing each method, helping others understand the code more easily.
In variable naming, num1, num2, and number are more descriptive than a and b, although there is potential for improvement in all cases.

See the difference! It’s amazing🤯

Conclusion ✅
The responsibility of measuring code quality is standing for each developer in the project from the team lead, developer, and tester.
You should always make code reviews to check your code quality and enhance it.
Applying code quality standards ensures your code readability and maintainability of all time, making it easier for developers to collaborate and understand each other’s code.
See you in the next part where we will learn more about tools to measure code quality and tips to improve our code

I hope that I can help you to understand this topic well. This checklist you can go back to it at any time.

Image description

That's it! Start to check your Code Quality! Connect with me on LinkedIn and GitHub for more articles and insights. If you have questions, contact me.
https://linktr.ee/rowan_ibrahim

Remember, "Later Equals Never." 😉

Top comments (0)