Найти в Дзене

Запахи кода (Code Smells). Примеры на PHP. Часть 1

Code Smells - это признаки некачественного кода, которые по тем или иным причинам приводят к различным проблемам. 1. Длинный метод (Long Method) Метод делает много всего. Из-за этого его сложно: Простой пример: function processOrder(Order $order)
{
// Валидация заказа
if (!$order->isValid()) {
throw new Exception("Invalid order");
}
// Сохранение в БД
$db = new Database();
$db->save($order);
// Отправка email
$mailer = new Mailer();
$mailer->sendConfirmation($order->getUserEmail(), "Your order is processed!");
// Логирование
$logger = new Logger();
$logger->log("Order processed: " . $order->getId());
// Обновление кэша
$cache = new Cache();
$cache->invalidate("orders");
} Как исправить: Разделить на отдельные методы (validateOrder, saveOrder, sendConfirmationEmail и т. д.). 2. Повторяющийся код (Duplicated Code) Даже самое первое переиспользование кода уже начинает доставлять проблемы. Пример: function calculateT

Code Smells - это признаки некачественного кода, которые по тем или иным причинам приводят к различным проблемам.

1. Длинный метод (Long Method)

Метод делает много всего. Из-за этого его сложно:

  • Читать
  • Понять
  • Масштабировать
  • Переиспользовать

Простой пример:

function processOrder(Order $order)
{
// Валидация заказа
if (!$order->isValid()) {
throw new Exception("Invalid order");
}

// Сохранение в БД
$db = new Database();
$db->save($order);

// Отправка email
$mailer = new Mailer();
$mailer->sendConfirmation($order->getUserEmail(), "Your order is processed!");

// Логирование
$logger = new Logger();
$logger->log("Order processed: " . $order->getId());

// Обновление кэша
$cache = new Cache();
$cache->invalidate("orders");
}

Как исправить: Разделить на отдельные методы (validateOrder, saveOrder, sendConfirmationEmail и т. д.).

2. Повторяющийся код (Duplicated Code)

Даже самое первое переиспользование кода уже начинает доставлять проблемы.

Пример:

function calculateTotalPrice(array $items)
{
$total = 0;
foreach ($items as $item) {
$total += $item->price * $item->quantity;
}
return $total;
}

function calculateDiscountPrice(array $items)
{
$total = 0;
foreach ($items as $item) {
$total += $item->price * $item->quantity;
}
return $total * 0.9;
}

Как исправить: Вынести общую логику в отдельный метод.

3. Большое количество параметров (Long Parameter List)

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

Пример:

function createUser(
string $name,
string $email,
string $password,
string $address,
string $phone,
bool $isAdmin = false,
bool $sendEmail = true
) {
// ...
}

Как исправить: Использовать паттерн DTO (Data Transfer Object) или массив с валидацией.

4. Магические числа и строки (Magic Numbers/Strings)

Непонятные значения в коде без пояснений

if ($user->age > 18) {
// ...
}

if ($status === "A") {
// ...
}

Как исправить: Решается в зависимости от контекста, но в основном можно использовать:

  • Enum
  • Константы класса
  • Приватные свойства класса
  • Использовать config
  • Переменные

5. Избыточные условия (Complex Conditional)

Такие условия всегда сложно читать

Пример:

if (($user->isAdmin && $user->isActive) || ($post->isPublished && $post->hasComments)) {
// ...
}

Как исправить: Вынести условие в отдельный метод с понятным названием

6. Класс-божество (God Object)

Класс огромный, который делает все, что только может. Если класс занимает больше 300 строк, то стоит уже задуматься над его рефакторингом

Пример:

class SuperManager {
public function manageUsers() { /* ... */ }
public function processOrders() { /* ... */ }
public function generateReports() { /* ... */ }
public function sendEmails() { /* ... */ }
}

Как исправить: Разделить на UserManager, OrderProcessor, ReportGenerator и т. д.

7. Жёсткая зависимость (Hard-Coded Dependency)

Прямое создание объектов внутри класса

Пример:

class OrderService
{
public function process()
{
$logger = new FileLogger(); // Жёсткая привязка к FileLogger
$logger->log("Processing order...");
}
}

Как исправить: Внедрять зависимость через DI (Dependency Injection)

8. Игнорирование ошибок (Error Ignoring)

Использование @ для подавления ошибок.

Пример:

$data = @file_get_contents('nonexistent_file.txt');

Как исправить: Достаточно просто обрабатывать ошибки

9. Избыточные комментарии (Redundant Comments)

Комментарии ради комментариев или PHPDoc, который дублирует итак явные вещи

Пример 1:

// Увеличивает счетчик на 1
$counter++;

Пример 2:

/**
* Возвращает пользователя
* @param int $id
* @return User
*/
public function getUser(int $id): User
{
// ...
}

Как исправить: Удалить избыточные комментарии. При необходимости комментария, коментировать по принципу "почему так", а не "что это"

10. Null при отсутствии результата (Null return)

Возвращать null при любой непонятной ситуации плохая практика, так как всегда нужно обрабатывать это дополнительным if условием

Пример:

public function getUser(int $id): ?User
{
$user = User::
find($id);
if (!$user) {
return null;
}

return $user;
}

Как исправить: В зависимости от ситуации можно либо выбрасывать исключение, либо использовать паттерн Null Object