← Назад к вопросам
По каким признакам понимаешь что код плохой?
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-код должен быть предсказуемым, тестируемым и понятным новым членам команды без длительного погружения в кодбазу.