Blog post

What is Clean Code?

Gabriel Vivas photo

Gabriel Vivas

Product Manager

5 min read

  • Clean Code
  • How we work

If you’ve followed us for a while, you most likely noticed that we changed the way we describe what we do: from “code quality” to “continuous code inspection,” then “code quality and code security”… It feels like in the last couple of years, we finally managed to settle on what we had been looking for from the beginning: Clean Code. 


But what is Clean Code, and what does it encompass?

This is about causes and (clean) code

The problem that we solve at Sonar is a big problem, which also has a lot of ramifications. We help to improve productivity, reduce risk and downtime, and increase code ownership. We impact the source code but also, of course, indirectly, the software itself. 


In the past, when describing what we do, we mixed all of these descriptions, leading to inconsistencies (in the best case) and difficulty connecting the dots for our community. Around two years ago, we decided to solve this issue and launched an internal initiative to explain better what we do. 


To make a (very) long story short, we eventually settled on three things:

  1. Our focus is exclusively on code, and this is how we should describe what we do
  2. We should focus on the cause of issues, not on their potential consequences
  3. We name what we do Clean Code


Once these decisions were made, you started to see “Clean Code” appearing here and there. Problem solved? Not quite. We know what we do and our focus, but we still have a gap: how do we classify the nonconformities to Clean Code if we want to remain rooted in the actual code and not in the consequences?


So, we started another project to develop a classification, aka taxonomy.

The Clean Code Taxonomy

The foundation of the Clean Code taxonomy is code that is clean and code that has the following properties: consistent, intentional, adaptable, and responsible.


In other words, whenever code has an issue, this issue will “break” one of these categories.


Let’s now review the four categories in detail.

Consistent

Code should be consistent and follow a common style. This means that all the code, even if worked on by different people over time, should have a similar appearance and adhere to established patterns. This consistency should apply not only within a specific codebase but also ideally across the entire programming language ecosystem.

Example 1:

Code should be formatted. For example, even if you are not familiar with Java code, you probably expect to see consistent indentation in the following code. It’s not about tabs versus spaces, it’s about consistency.


Non-compliant code:

class Foo {
  public int a;
    public int b;

  public void doSomething() {
    if(something) {
          doSomethingElse();
  }
  }
}

Compliant code:

class Foo {
  public int a;
  public int b;

  public void doSomething() {
    if(something) {
      doSomethingElse();
    }
  }
}

Read more: https://sonarsource.github.io/rspec/#/rspec/S1120/java

Example 2:

Code should be idiomatic and follow syntax conventions. For example, in C++ >= 11 ​​type aliases can be declared via either typedef or using, however, you should prefer the latter for modern code.


Non-compliant code:

typedef void (*FunctionPointerType)(int);

Compliant code:

using FunctionPointerType = void (*)(int);

Read more: https://sonarsource.github.io/rspec/#/rspec/S5416/cfamily

Example 3:

Code should be easily identifiable. Consider code written in C#, where PascalCase is used for all identifiers except parameter names. In this context, using underscores or other casing styles to differentiate words in an identifier is unacceptable.


Non-compliant code:

class my_class {...}
class SOMEName {...}

Compliant code:

class MyClass {...}
class SomeName {...}

Read more: https://sonarsource.github.io/rspec/#/rspec/S101/csharp

Intentional

Intentional code reads like it was written with attention and care to convey its purpose. The code should be self-explanatory and only allow for one interpretation. Every instruction makes sense, adequately forms, and simply conveys its behavior. The code should not be ambiguous or leave room for guessing.

Example 1:

Code should be clear and straightforward. Take this Python code as an example, and you'll notice that variables `message` and `i` are defined but never used. When readers encounter such cases, they might wonder if it's a coding error that was supposed to do something else or if it's just leftover code that can be safely deleted.


Non-compliant code:

def hello(name):
    message = "Hello " + name
    print(name)
for i in range(10):
    foo()

Compliant code:

def hello(name):
    message = "Hello " + name
    print(message)
for _ in range(10):
    foo()

Read more: https://sonarsource.github.io/rspec/#/rspec/S1481/python

Example 2:

Code should only contain instructions that are logically sound. For instance, in JavaScript, there's `NaN`, which stands for 'Not-a-Number.' It represents a numeric data type that isn't a valid number. `NaN` is not equal to any value, even itself, and this behavior can lead to unexpected results.


Non-compliant code:

if (a !== NaN) {
  console.log("this is always logged");
}

Compliant code:

if (!isNaN(a)) {
  console.log("a is not NaN");
}

Read more: https://sonarsource.github.io/rspec/#/rspec/S2688/javascript

Example 3:

Code should be thorough. An example in PHP is the use of secure cookies. The method `setcookie` allows you to create cookies that can be transmitted via HTTP by default, making their contents readable. Since cookies often carry sensitive data, it's important to ensure they are transferred securely to fulfill their intended purpose. You need to pass a last argument to enable HTTPS only.


Non-compliant code:

$value = "sensitive data";
setcookie($name, $value, $expire, $path, $domain);

Compliant code:

$value = "sensitive data";
setcookie($name, $value, $expire, $path, $domain, true);

Read more: https://sonarsource.github.io/rspec/#/rspec/S2092/php

Example 4:

Code should be efficient and not waste resources needlessly. For example, most Linux package managers create a cache by default when working with Docker. Unless you remember to remove these files in your Dockerfile, they will increase the size of your image without providing any additional value.


Non-compliant code:

RUN apt-get update \
  && apt-get install nginx

Compliant code:

RUN apt-get update \
  && apt-get install nginx \
  && apt-get clean

Read more: https://sonarsource.github.io/rspec/#/rspec/S6587/docker

Adaptable

When code is adaptable, it’s segmented and organized in a way that makes it easier to manage and see the relationships between code. The code should be structured for easy and confident evolution. It should simplify the process of extending or repurposing its parts and encourage localized changes without causing unintended side effects.

Example 1:

Code should be distinct and minimize duplication. For instance, duplicating string literals raises the risk of errors when making updates since each occurrence must be changed separately. A better approach is to use constants that can be referenced from multiple places, allowing updates to be made in a single location. Here’s an example using Ruby.


Non-compliant code:

def foo()
  prepare('action random1')
  execute('action random1')
  release('action random1')
end

Compliant code:

def foo()
  action1 = 'action random1'
  prepare(action1)
  execute(action1)
  release(action1)
end

Read more: https://sonarsource.github.io/rspec/#/rspec/S1192/ruby

Example 2:

Code should be focused, with each unit having a specific and limited scope. For instance, in Swift, it's best practice to keep types, such as classes, in separate files. This helps prevent an excessive accumulation of instructions or an overwhelming amount of complexity within a single file.


Non-compliant code:

class MyViewController: UIViewController {
  // …
}
extension MyViewController: UIScrollViewDelegate {
  // …
}
class UnrelatedController: UIViewController {
  // …
}

Compliant code:

class MyViewController: UIViewController {
  // …
}
extension MyViewController: UIScrollViewDelegate {
  // …
}

Read more: https://sonarsource.github.io/rspec/#/rspec/S1996/swift

Example 3:

Code should be modular, and a key aspect of this is encapsulation. In Object-Oriented languages, encapsulation often involves making fields private. This way, the class retains control over the details of its internal representation and prevents other parts of the code from having too much knowledge about its inner workings.


However, there are multiple levels of encapsulation, and even minor improvements can make a difference. For example, if you're working with VB.Net, which allows publicly accessible fields, it's better to avoid using them and instead use properties. Properties work similarly to fields but are part of the interface and can be overridden by getters and setters.


Non-compliant code:

Class Foo
    Public Bar = 42
End Class

Compliant code:

Class Foo
    Public Property Bar = 42
End Class

Read more: https://sonarsource.github.io/rspec/#/rspec/S2357/vbnet

Example 4:

Code should include tests that instill confidence when making changes. Ideally, we should prioritize comprehensive functional test coverage. However, accurately measuring it can be challenging. Nonetheless, it's essential to ensure that test coverage is not so low that you can fear modifying the code.


There are odd examples, where you have a test folder or test files, without actual test cases inside, which can mislead other developers: https://sonarsource.github.io/rspec/#/rspec/S2187/

There are also cases where tests are skipped and accidentally committed like that, which might go unnoticed if not tracked in any way: https://sonarsource.github.io/rspec/#/rspec/S1607/

Responsible

Code should be mindful of its ethical obligations concerning data and its potential influence on societal norms. Whether it's a matter of professional duty, providing peace of mind, or championing inclusivity, the bottom line is that code should not present an ongoing risk of unintentionally harming third parties. This applies regardless of whether developers bear immediate liability.

Example 1:

Code should avoid hard-coding secrets. While it may be tempting for internal applications or when you believe the source code is secure, the truth is that responsible code should never store secrets. If malicious parties access the code, secrets can be inadvertently exposed and exploited. This risk not only affects the software itself. It can have far-reaching consequences, impacting the system and third parties.


Here’s a simplified example using Go:


Non-compliant code:

func connect()  {
  user := "root"
  password:= "supersecret"

  url := "login=" + user + "&passwd=" + password
}

Compliant code:

func connect()  {
  user := getEncryptedUser()
  password:= getEncryptedPass()

  url := "login=" + user + "&passwd=" + password
}

Read more: https://sonarsource.github.io/rspec/#/rspec/S2068/go

Example 2:

Code should be lawful. It should respect basic licensing and copyright regulations. It exercises the creator’s rights and honors other’s rights to license their code.


One common example is companies enforcing copyright headers in their code files:

/*
 * SonarQube, open source software for clean code.
 * Copyright (C) 2008-2023 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

Read more: https://sonarsource.github.io/rspec/#/rspec/S1451/

Example 3:

Code should be respectful and inclusive. It should avoid employing discriminatory or offensive language and opt for inclusive terminology whenever a suitable alternative communicates the same meaning.


A regular expression can be used to track identifier names and comments, for example:


Non-compliant code:

Master / Slave
Blacklist / Whitelist

Compliant code:

Primary / Secondary
Denylist / Allowlist

Read more: https://sonarsource.github.io/rspec/#/rspec/?query=naming%20convention

And so what?

First, we feel very good about this classification (by the way, each category also breaks down into subcategories). We think this is a solid foundation for Clean Code. 


Now, we want to gradually roll out this detailed definition of Clean Code in Sonar products. Starting with the way we classify issues in the code. The first step is already available in SonarCloud, SonarLint, and SonarQube 10.2.


In addition, we will start working on classifying the consequences for the software when the code isn't clean, such as security, reliability, maintainability, etc.


See the community announcement for screenshots and more information: https://community.sonarsource.com/t/introducing-clean-code-in-our-products/98431


Share your feedback!



Get new blogs delivered directly to your inbox!

Stay up-to-date with the latest Sonar content. Subscribe now to receive the latest blog articles. 

By submitting this form, you agree to the Privacy Policy and Cookie Policy.