Код должен читаться как хорошо написанная проза. Вот почему вы должны быть осторожны с логическими значениями.

Эта статья является частью углубленного курса по чистому коду под названием Чистый код: резко увеличьте вашу карьеру программиста за 7 дней, вы можете ознакомиться с ней. В настоящее время он доступен со скидкой 87%.

Поскольку вы часто используете их в операторах if, у вас есть шанс сделать код действительно хорошо читаемым ИЛИ сделать код действительно дрянным и трудным для чтения. Давайте посмотрим на пример:

if(person.hunger < 6.8 && person.money >= getClosestOpenResurant(person.location).dinnerPrice && day() < 6){
   // make an order
}

Вы впервые видите этот код, вы его понимаете? Или вам нужно время подумать об этом? Я уверен, что со временем вы разберетесь, но вам нужно время. Теперь давайте извлечем логические значения и дадим им имена. Посмотрим, хорошо ли читается код:

boolean personIsHungry = person.hunger < 6.8;
boolean personCanAffortDinner = person.money >= getClosestOpenResurant(person.location).dinnerPrice;
boolean isWeekDay = day() < 6;
if(personIsHungry && personCanAffortDinner && isWeekDay) {
   // make an order
}

А теперь представьте, что вы впервые видите этот код. Давайте прочитаем утверждение if. Если человек голоден, и он может позволить себе обед и сейчас рабочий день - тогда сделайте заказ. Думаю, так лучше, не так ли? Но мне все равно это не нравится. Видите ли, первые два логических значения работают с объектом Person. Эта логика может быть инкапсулирована внутри объекта. Также мы можем создать объект для логики буднего дня:

class Person {
   // fields here
	
   pubic boolean isHungry() {
      return hunger < 6.8
  }
	
   public boolean canAffortDinner() {
      return person.money >= ResturantUtils.getClosestOpenResurant(person.location).dinnerPrice
   }
}
class TimeOperations {
   public static boolean isWeekday() {
      return day() < 6;
   }
}
if(person.isHungry && person.canAffortDinner && TimeOperations.isWeekDay) {
   // make an order
}

Теперь у нас есть класс Person с логическими методами в нем. И у нас есть класс TimeOperations с методом isWeekday. Теперь давайте посмотрим на оператор if. Это одна строка читаемого кода. Если вы увидите это впервые, у вас не будет проблем с пониманием того, что происходит. Это потому, что мы скрываем детали внутри именованных блоков кода. Вы должны делать это не только с логическими значениями, но и со всем кодом, который вы пишете.

Я вижу, что многие люди пишут такой код:

public void deleteUser(int id) {
   if (loggedUser != null) {
      if(loggedUser.sessionExpired()) {
         // log erorr and throw
      }
      if(loggedUser.isNotAdmin()) {
         // log erorr and throw
      }
      userRepository.delete(id);
   } else {
      // throw
   }
}

С большим количеством гнездовий. Код вложенности трудно читать. Старайтесь изо всех сил избегать этого. Вы видите, где мы удаляем пользователя? Это наша основная логика. Остальное - детали. Посмотрите, как логика основного метода обернута вокруг проверок и деталей. Если мне нужно понять эту логику, мне нужно будет просмотреть весь другой код, окружающий ее, а затем я перейду к строке, которую хочу увидеть. И нас может не волновать другой код. В этом случае мы можем просто выполнить проверки отдельно от бизнес-логики. Для этого нам просто нужно перевернуть первый if, а затем скопировать остальные проверки, следующие за ним:

public void deleteUser(int id) {
   if (loggedUser == null) {
      // throw
   }
   if(loggedUser.sessionExpired()) {
       // log erorr and throw
   }
   if(loggedUser.isNotAdmin()) {
      // log erorr and throw
   }
   userRepository.delete(id);	
}

Конечно, в этом примере это работает. У вас может быть другой случай. Просто попробуйте отделить проверки и детали от основной логики.

Посмотрите, как мы развернули бизнес-логику. Намного лучше. Я хочу, чтобы вы увидели две вещи:

  1. Во-первых, обратите внимание на различия между двумя методами и подумайте о них.
  2. Во-вторых, придумайте способ сделать метод deleteUser более чистым. Что мы можем сделать, чтобы бизнес-логика была в центре внимания?

Что мы можем сделать ... это правильно, ребята, извлеките проверки в отдельный метод следующим образом:

public void deleteUser(int id) {
   validatePermissions();
   userRepository.delete(id);
}
private void validatePermissions() {
   if (loggedUser == null) {
      // throw
   }
   if(loggedUser.sessionExpired()) {
      // log erorr and throw
   }
   if(loggedUser.isNotAdmin()) {
      // log erorr and throw
   }
}

Посмотрите метод deleteUser сейчас, так намного лучше. У нас есть одна строка для проверки и одна строка для фактической логики метода. Если мы хотим увидеть проверки, мы заходим внутрь validatePermissions method. Опять же, нам не нужно загромождать методы деталями. Посмотрите разницу между методами. Вы можете ясно видеть, что лучше.

Прежде чем вы отправитесь - наш удивительный курс по чистому коду в настоящее время доступен со скидкой 87%

Если вам понравилась эта статья, вам понравится наш курс:

  • 46 лекций
  • 3+ часа контента
  • Работа над реальным проектом, который проверит ваши знания
  • 27 загружаемых ресурсов
  • 30-дневная гарантия возврата денег

Вы можете записаться на курс здесь - Чистый код: взлетайте до небес за 7 дней