Что такое чистый код?

Вы пишете коды, которые работают? Это чистый код? Могут ли другие понять, как работают ваши коды? Что ж, чистый код — это не тот код, который просто работает. Речь идет о том, легко ли читать и понимать код.

Как разработчик, мы потратили много времени на чтение и понимание кода. Нам нужно понять код, чтобы исправить ошибку, добавить функцию или углубиться в код, написанный нашими коллегами. Это должно быть легко, потому что если это будет сложно, мы потеряем много времени и, конечно же, продуктивности.

Так что же такое чистый код? Это код, который¹

  • Читабельно и со смыслом
  • Легко понять
  • К точке
  • Избегайте неинтуитивных имен, сложной вложенности и больших блоков кода.
  • Следуйте лучшим практикам и шаблонам разработки программного обеспечения
  • Простота обслуживания

Давайте проверим фрагменты кода ниже

function check(capacity: any){
  if(capacity && capacity.length > 0){
    for(let i=0;i<=capacity.length;i++){
      if(capacity[i].type === 'LARGE'){
        if(capacity[i].status === 'ACTIVE'){
          if(capacity[i].total > 1000){
            triggerStatus(capacity[i].total);
          } else {
            process(capacity[i].total);
          }
        } else {
          sendNotification();
        }
      } else {
        if(capacity[i].status === 'ACTIVE'){
          if(capacity[i].total > 100){
            triggerStatus(capacity[i].total);
          } else {
            process(capacity[i].total);
          }
        } else {
          sendNotification();
        }
      }
    }
  }
}

Можете ли вы легко понять, что делают фрагменты кода? Если сложно, значит, это не чистый код.

Это то же самое, что и «Чистая архитектура»? Это другое. В «Чистом коде» мы сосредоточились на том, как писать код для одной задачи/файла. В «Чистой архитектуре» мы сосредоточились на том, где писать код во всей структуре проекта.

Выбор хороших имен для переменных, функций и классов¹.

Почему нейминг так важен? Давайте проверим фрагмент кода ниже

const as = new Entity();
as.save();

if(validate) {
 ...
}

Что именно делает код? что такое "как"? Что такое «сущность»? Что такое «валидировать»? это строка или логическое значение? Чтобы понять этот фрагмент, нам нужно больше информации, возможно, нам нужно глубоко погрузиться в функцию и класс и проверить, как они работают. Теперь давайте проверим фрагмент кода ниже

const user = new User();
user.save();

if(isValidated) {
 ...
}

На самом деле это тот же фрагмент кода, но гораздо более понятный. Мы можем понять, что делает код, не углубляясь в его функцию и класс. Мы можем предположить, что мы создаем пользователя, а затем сохраняем его, возможно, в базу данных. И «isValidated» удерживает значение, проверяя, был ли пользователь уже проверен или нет с логическим значением.

Поэтому осмысленное имя важно для улучшения читабельности кода.

Хорошо названные переменные, функции и классы позволяют читателям понять код, не углубляясь в его детали.

Как правильно назвать «Вещи»?

Примеры именования переменных¹

// A user object (id, name, gender)

// Bad Names Example:
const p= ...
const data = ...
// "p" and "data" could contain anything

// Okay Names Example:
const userData = ...
const person = ...
// "userData" is a bit redundant and "person" is to specific

// Good Names Example:
const user = ...
const seller = ...
// "user" is descriptive, "seller" is even more specific

// A user input validation (true / false)

// Bad Names Example:
const v = ...
const val = ...
// "v" could be anything and "val" could also stand for "value"

// Okay Names Example:
const correct = ...
const validatedInput = ...
// Both terms don't necessarily imply true/false value

// Good Names Example:
const isCorrect = ...
const isValid = ...
// Descriptive and value type is clear

Примеры именования функций и методов¹

// Save user data to a database

// Bad Names Example:
process()
handle()
// Both are very unspecific - what is being "processed" and "handled" ?

// Okay Names Example:
save()
storeData()
// at least we know that something is stored but we don't know what is that

// Good Names Example:
saveUser()
user.store()
// Very Clear especially the method
// Validate User Input

// Bad Names Example:
process()
save()
// Both are very unspecific

// Okay Names Example:
validateSave()
check()
// Not too specific

// Good Names Example:
validate()
isValid()
// What function does very clear 

Примеры именования классов¹

// User class

// Bad Names Example:
class UIdentity
class ObjectU
// Both are very unspecific

// Okay Names Example:
class UserObject
class ApplicationUser
// Both names have redundant information

// Good Names Example:
class User
class Member
// "User" is informative, and "Member" is more specific kind of user.

Избегайте сленга, непонятных сокращений и дезинформации¹

Сленг может кому-то или вашей команде покажется крутым и забавным. Но использование таких фраз для именования вещей не поможет нам достичь чистого кода. Особенно, когда новый участник проекта пытается глубоко погрузиться, ему будет нелегко понять, что делают эти методы.

Избегать:

member.screwThem()
user.burnOut()

Do:

member.remove()
user.showErrorMessage()

Непонятная аббревиатура также сделает наш код неудобным для чтения и приведет к непониманию.

Избегать:

insert(n)
let ymdt = '20230127CET'

Do:

insert(newUser)
let dateWithTimeZone = '20230127CET'

Дезинформационное название может ввести читателей в заблуждение. При таком именовании мы должны проверять использование «вещей» или углубляться в методы проверки информации.

Избегать:

let customerList = { customer1: ..., customer2: ... } // using list as name but not an array
let allCustomer = customer.filter() // using "all" phrase but stores filtered customer

Do:

let customer = { customer1: ..., customer2: ... }
let maleCustomer = customer.filter()

Будьте последовательны

Мы можем назвать методы глаголами фразы. Но некоторые глаголы имеют сходное значение. Мы должны быть последовательны, называя вещи. Это создаст те же шаблоны и улучшит читаемость нашего кода. Например:

getCustomer()
fetchCustomer()
retrieveCustomer()

Имя метода хорошее и описывает одно и то же. Это легко понять, но вы должны быть последовательны в своем проекте. Например, если вы решите использовать фразу «получить», сделайте следующее:

getCustomer()
getPrice()
getProduct()

Заключение

Переменные, функции/методы и классы с хорошими названиями позволяют читателям легко понять, что делает код, не углубляясь в него. Использование хороших имен улучшит читабельность нашего кода и упростит его обслуживание в соответствии с целью внедрения Cбережливого кода.

[1] Academind Максимилиана Шварцмюллера, Максимилиана Шварцмюллера. Чистый код: узнайте, как писать читаемый, понятный и, следовательно, пригодный для сопровождения код — шаг за шагом, на основе примеров. https://www.udemy.com/course/writing-clean-code/