Clean Code на Swift: принципы и примеры
Чистый код (Clean Code) — это не просто модный термин, а философия разработки, которая напрямую влияет на скорость создания фич, количество багов и удовольствие от работы. Для Swift-разработчиков, работающих над iOS и macOS приложениями, особенно важно писать код, который легко читать и поддерживать, ведь проекты живут годами, а команды меняются. В этой статье мы разберём основные принципы Clean Code применительно к Swift и рассмотрим конкретные примеры.
1. Именование: говорите на языке предметной области
Правильное именование — основа читаемого кода. Имена переменных, функций и классов должны отвечать на вопросы "что?" и "зачем?". Избегайте сокращений и однобуквенных имён (кроме i в коротких циклах).
Плохой пример:
func calc(a: Int, b: Int) -> Int { return a * b + 10}Хороший пример:
func calculateTotalPriceWithShipping(itemPrice: Int, shippingCost: Int) -> Int { return itemPrice + shippingCost}Для булевых переменных используйте префиксы is, has, should:
var isUserLoggedIn: Bool = falsevar hasCompletedOnboarding: Bool = trueИмена классов должны быть существительными ( UserManager, NetworkService ), а функции — глаголами или глагольными фразами ( fetchData(), validateEmail() ).
2. Функции: маленькие и с одной ответственностью
Каждая функция должна делать ровно одну вещь и делать её хорошо. Идеальная длина функции — 10-20 строк. Если функция превышает 30 строк — разбивайте её на более мелкие.
Плохой пример: функция, которая и валидирует, и сохраняет, и отправляет уведомление.
func processUser(_ user: User) { // Валидация guard !user.name.isEmpty else { return } guard user.age > 18 else { return } // Сохранение CoreDataManager.shared.save(user) // Уведомление NotificationCenter.default.post(name: .userDidRegister, object: nil)}Хороший пример: разделение на три отдельные функции.
func processUser(_ user: User) { guard isValid(user) else { return } saveUser(user) notifyUserRegistration()}
private func isValid(_ user: User) -> Bool { return !user.name.isEmpty && user.age > 18}
private func saveUser(_ user: User) { CoreDataManager.shared.save(user)}
private func notifyUserRegistration() { NotificationCenter.default.post(name: .userDidRegister, object: nil)}Также избегайте большого количества параметров. Если их больше трёх — объедините в структуру.
struct SearchConfig { let query: String let category: String? let page: Int let pageSize: Int}
func search(with config: SearchConfig) -> [Result] { ... }3. SOLID в Swift: практические примеры
Принципы SOLID — краеугольный камень чистого кода в объектно-ориентированных языках. Рассмотрим два ключевых принципа на примерах Swift.
Принцип единственной ответственности (SRP)
Класс должен иметь только одну причину для изменения. Не смешивайте логику сети и UI.
// Нарушение SRPclass UserViewController: UIViewController { func fetchUser() { URLSession.shared.dataTask(with: URL(string: "...")!) { ... } } func updateUI() { ... }}
// Исправлениеclass UserNetworkService { func fetchUser(completion: (User) -> Void) { ... }}
class UserViewController: UIViewController { let networkService = UserNetworkService() func loadUser() { networkService.fetchUser { [weak self] user in DispatchQueue.main.async { self?.updateU