← Назад к вопросам

По каким признакам понимаешь что код плохой?

1.3 Junior🔥 61 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Признаки плохого кода в iOS-разработке

Как опытный iOS-разработчик, я оцениваю код по совокупности критериев, которые можно разделить на несколько категорий. Плохой код не просто работает — он создаёт долгосрочные проблемы для поддержки, масштабирования и командной работы.

1. Нарушение принципов SOLID и архитектурных паттернов

Наиболее явный признак — игнорирование базовых принципов объектно-ориентированного проектирования:

  • God Object: класс ViewController, который занимается всем — от работы с сетью до парсинга JSON и обновления интерфейса
  • Жёсткие зависимости: прямое создание зависимостей внутри классов вместо инъекции
// ПЛОХО: Нарушение Single Responsibility Principle
class ProfileViewController: UIViewController {
    func loadUserData() {
        let url = URL(string: "https://api.example.com/user")!
        URLSession.shared.dataTask(with: url) { data, _, _ in
            let user = try? JSONDecoder().decode(User.self, from: data!)
            DispatchQueue.main.async {
                self.nameLabel.text = user?.name
                self.saveToCoreData(user)
                self.updateAnalytics()
            }
        }.resume()
    }
}

2. Проблемы с читаемостью и поддерживаемостью

  • Магические числа и строки: разбросанные по коду числа, значения которых не очевидны
  • Избыточно сложные конструкции: цепочки из 5+ опциональных связываний или гигантские closure
  • Отсутствие документации для сложной бизнес-логики
// ПЛОХО: Магические числа и сложная опциональная цепочка
func calculateDiscount(price: Double?) -> Double? {
    return price??.rounded() ?? 0 * 0.15 * 1.2 / (1 + 0.18) // Что означают эти числа?
}

3. Игнорирование iOS-специфичных best practices

  • Утечки памяти: retain cycles в closure, сильные ссылки в NotificationCenter
  • Неправильная работа с main thread: обновление UI из фоновых потоков или блокировка главного потока
  • Жёсткие константы размеров и отступов, которые ломают адаптивность
// ПЛОХО: Potential retain cycle и работа с UI не из main thread
class DataLoader {
    var completion: ((Data) -> Void)?
    
    func loadData() {
        URLSession.shared.dataTask(with: someURL) { data, _, _ in
            self.completion?(data!) // Потенциальный retain cycle
            self.updateUI(with: data) // UI обновляется не из main thread
        }.resume()
    }
}

4. Отсутствие тестируемости

  • Тight coupling: зависимости захардкожены, нельзя подменить mock-объектами
  • Глобальное состояние: использование синглтонов для хранения изменяемого состояния
  • Отсутствие разделения на слои: бизнес-логика перемешана с UI-кодом
// ПЛОХО: Нетестируемый код из-за жёстких зависимостей
class OrderProcessor {
    func processOrder(_ order: Order) {
        let apiService = APIService.shared // Глобальный синглтон
        let database = CoreDataManager.shared // Ещё один синглтон
        // Невозможно протестировать с mock-сервисами
    }
}

5. Антипаттерны в управлении памятью и производительности

  • Сильные ссылочные циклы в closure и делегатах
  • Reuse identifier как строковые литералы в нескольких местах
  • Массивные операции на main thread: синхронные сетевые запросы, сложные вычисления
// ПЛОХО: Массивная операция на главном потоке
func processImageData() {
    let largeData = loadHugeImage() // Блокирует UI
    let processed = applyFilters(largeData) // Ещё больше блокирует
    imageView.image = processed
}

6. Нарушения code style и соглашений

  • Несогласованные naming conventions: то fetchData(), то getUsers(), то loadPosts
  • Слишком длинные методы и классы (более 100 строк)
  • Нарушения guidelines Apple: например, изменение frame во время анимации без layoutIfNeeded()

7. Признаки, которые видны без глубокого анализа

  • Частые merge conflicts в одних и тех же файлах
  • "Comment-out" код, оставленный "на всякий случай"
  • Дублирование логики в разных частях приложения
  • Страх вносить изменения в определённые модули

Ключевой индикатор — когда простое изменение (добавление нового поля, изменение формата отображения) требует правок в 10+ файлах и затрагивает несколько слоёв приложения. Хороший iOS-код должен быть предсказуемым, тестируемым и понятным новым членам команды без длительного погружения в кодбазу.