Чистый код на Swift: как писать так, чтобы коллеги не проклинали вас

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как писать чистый код на 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

Блоги

Рекомендаций по книгам