Как писать чистый код на Swift: руководство для тех, кто уважает себя и коллег
Каждый разработчик хотя бы раз открывал проект, написанный полгода назад, и не мог понять, что там происходит. Или получал на код-ревью комментарий: «Это можно было написать проще». Знакомо? Если да — эта статья для вас.
Чистый код на Swift — это не просто прихоть перфекциониста. Это инструмент, который экономит часы дебаггинга и нервов. Когда вы пишете аккуратно, вы не только ускоряете свою работу, но и делаете проект прозрачным для команды. Давайте разберём, как превратить ваш Swift-код в произведение искусства.
Правило №1: Именование — всему голова
Самый частый грех — назвать переменную x или temp. Потом приходит другой разработчик и гадает: «Что за x? Координата? Количество?»
В Swift принято давать имена, которые читаются как предложения. Это не просто красиво — это помогает сразу понять, что делает код.
// Плохо
let a = 5.0
var b = "John"
// Хорошо
let discountRate = 5.0
var userName = "John"
Для функций и методов действует то же правило. Название должно отвечать на вопрос «Что делает этот метод?». Используйте глаголы в повелительном наклонении:
// Плохо
func data() -> [String] { ... }
// Хорошо
func fetchUsers() -> [String] { ... }
А если функция возвращает булево значение, начинайте название с is, has или contains:
func isUserLoggedIn() -> Bool
func hasValidEmail() -> Bool
Правило №2: Опционалы — не враги, а инструменты
Многие новички боятся опционалов и пытаются от них избавиться любой ценой. Они пишут if let везде или, что ещё хуже, форс-анврапят. Но чистый код на Swift — это код, который безопасно работает с nil.
Запомните: ! — это крик о помощи. Используйте его только если вы абсолютно уверены, что значение не nil (например, при работе с IBOutlet).
// Опасный код
let name = optionalName!
// Безопасный вариант
guard let name = optionalName else {
return
}
print(name)
А для цепочек опционалов используйте ? и nil-coalescing:
let userCity = user?.address?.city ?? "Неизвестно"
Этот код не упадёт, даже если user или address окажутся nil. И читается он как обычное предложение: «Город пользователя или "Неизвестно"».
Правило №3: Структуры вместо классов (где можно)
В Swift есть и классы, и структуры. Но многие по привычке везде используют классы. А зря. Структуры — это value types, и они безопаснее в многопоточном коде. Плюс они копируются, а не ссылаются, что снижает риск побочных эффектов.
Используйте структуру, если:
- Нужно хранить данные без сложной логики
- Нет необходимости в наследовании
- Объект не должен быть изменяемым после создания
// Лучше структура
struct User {
let id: Int
var name: String
}
// Класс — только если нужно наследование или reference semantics
class ViewController: UIViewController { ... }
Кстати, Apple рекомендует использовать структуры для моделей данных. Это один из главных принципов чистого кода на Swift.
Правило №4: Протоколы — ваши лучшие друзья
Протоколы в Swift — это не просто интерфейсы. Это способ сделать код гибким и тестируемым. Вместо того чтобы привязываться к конкретному классу, работайте через протокол.
protocol NetworkServiceProtocol {
func fetchData(completion: @escaping (Result<Data, Error>) -> Void)
}
class APIService: NetworkServiceProtocol { ... }
class MockService: NetworkServiceProtocol { ... }
Теперь вы можете легко подменить реальный сервис на мок для тестов. И не нужно менять код в других классах.
Ещё один приём — использование протоколов для разделения ответственности. Не пишите один гигантский протокол. Лучше разбейте на несколько маленьких:
protocol SignInHandler { ... }
protocol SignUpHandler { ... }
protocol PasswordResetHandler { ... }
Класс, который работает только с регистрацией, не должен знать о сбросе пароля. Это делает код чище и проще для понимания.
Правило №5: Избегайте магических чисел
Магические числа — это числовые значения, которые появляются в коде без объяснения. Что такое 86400? А 0.7? Через месяц вы сами не вспомните.
// Плохо
let timeout = 30.0
// Хорошо
let requestTimeoutInterval: TimeInterval = 30.0
Ещё лучше — вынести такие константы в отдельную структуру или enum:
enum Constants {
static let maxRetryCount = 3
static let defaultAnimationDuration: TimeInterval = 0.3
}
Теперь код говорит сам за себя. И если нужно изменить таймаут — вы знаете, куда смотреть.
Правило №6: Пишите читаемые функции
Функция должна делать одну вещь и делать её хорошо. Если вы видите, что функция занимает 50 строк — скорее всего, её нужно разбить.
Идеальная функция:
- Имеет понятное название
- Принимает 1-3 параметра (не больше)
- Возвращает результат или изменяет состояние
- Не имеет побочных эффектов (если это не предполагается)
// Плохо: функция делает всё сразу
func processUserData() {
// 10 строк: парсинг JSON
// 15 строк: валидация
// 20 строк: сохранение в базу
}
// Хорошо: разделение ответственности
func parseUser(from json: Data) -> User? { ... }
func validateUser(_ user: User) -> Bool { ... }
func saveUser(_ user: User) { ... }
Такие функции легко тестировать и переиспользовать. А ещё их приятно читать.
Правило №7: Комментарии — это не учебник
Хороший код не требует комментариев. Он должен быть понятен сам по себе. Если вам хочется написать комментарий — подумайте, может, стоит переименовать переменную или разбить функцию?
// Плохой комментарий
// Увеличиваем счетчик на 1
counter += 1
// Хороший комментарий — объяснение "почему"
// Используем Int64, чтобы избежать переполнения на 32-битных устройствах
let totalCount: Int64 = ...
Комментарии нужны для сложной бизнес-логики, описания неочевидных решений или для временных «todo». В остальных случаях — код должен говорить сам.
Правило №8: Используйте SwiftLint