Написание качественного кода — это непрерывный процесс совершенствования.
Все мы совершенствуемся с годами, если продолжаем практиковаться. Код, который вы пишете сегодня, вероятно, лучше, чем тот, который вы писали два года назад, и, скорее всего, он будет хуже, чем тот, который вы напишете через год. И это нормально, это часть процесса.
Итак, если вы хотите постоянно улучшать качество кода, вот несколько небольших советов, которые помогут вам на этом пути.
1. Используйте паттерн расширения для группировки фрагментов кода
Вы можете группировать код настроек в одном расширении, делегатов — в другом и так далее. Это облегчит чтение и сопровождение в будущем.
// MARK: - Setup extension HomeViewModel { func configureInitialState() { ... } func fetchCards() { ... } } // MARK: - Actions extension HomeViewModel { func search(text: String) { ... } func addCard(_ card: Card) { ... } }
2. Определите максимальное количество строк в файле
И придерживайтесь его. Если вы превысите это число, разбейте файл на два или более файлов. Можно даже использовать шаблон расширения, который мы рассматривали ранее.
3. Создавайте переменные и функции с описательными именами
Лучшая документация для вашего кода — это код автодокументированный. Основой этой концепции является наличие описательных имен. Кроме того, при возможности используйте плейсхолдеры параметров.
var result = 3 // Not the same as: let numberOfSessions = 3 func update(id: Int, amount: Int) { .. } // Not the same as: func updateBalance(toUser userID: Int, with amount: Int) { .. }
4. Используйте преимуществ typealias
Добавьте в свой код больше семантики, используя typealias. Когда кто-то впервые посмотрит на ваш код, ему будет легче понять его.
typealias ApiHeaders = [String:String] func getHeaders() -> ApiHeaders { var headers = ApiHeaders() headers["x-api-token"] = "asf232asgf5" headers["content"] = "application/json" return headers }
5. Позаботьтесь о «неправильном пути».
Что происходит при возникновении ошибки? Сообщаете ли вы об этом пользователю? Даете ли вы ему возможность повторить действие? Мы всегда в первую очередь концентрируемся на правильном пути и, как правило, забываем о последующей обработке ошибок.
// Avoid this approach do { // Perform some task ... } catch { print(error) } ------ struct SinginView: View { @State private var showingAlert = false @State private var alertMessage = "" var body: some View { VStack { ..... Button("Sign In") { tryToSignin() } } .alert("Error", isPresented: $showingAlert, actions: Button("Ok") {} }, message: { Text(alertMessage) }) } } extension SinginView { func tryToSignin() { do { // Perform some task ... } catch { showingAlert = true alertMessage = error.localizedDescription } } }
6. Опишите принудительное разворачивание и индексы
Принудительное разворачивание nil-объектов и вышедшие за пределы индексы — одна из наиболее распространенных причин сбоев. Их легко избежать, написав всего пару лишних строк.
let intString = ... // some value you get from a server let int = Int(intString) // Avoid print(int!) // Go safe with if-let if let int = Int(intString) { print(int) } let array = [.....] // Bunch of elements // Add an extra safety net to access the values extension Array { public subscript(safeIndex index: Int) -> Iterator.Element? { return index >= 0 && index < endIndex ? self[index] : nil } } let numbers = [10, 23, 12, 63, 1, 3] let number1 = numbers[safeIndex: 0] // = 10 let number2 = numbers[safeIndex: 6] // = nil
7. Правильно работайте с конфиденциальной информацией
Хешируете ли вы пароли перед отправкой на сервер? Храните ли вы конфиденциальную информацию, например, ключи API, в keychain?
Если вам нужна простая обёртка для использования, вы можете посмотреть мою статью об этом.
8. Избегайте дублирования кода
Если вам приходится писать один и тот же кусок кода дважды, это индикатор необходимости рефакторинга. Если нужно написать в третий раз, то это обязательное действие.
9. Избегайте жесткого прописывания сообщений непосредственно в коде
С годами я пришел к выводу, что лучше всего иметь либо менеджер для централизации всех сообщений, либо непосредственно локализовать их. Таким образом, если вы используете одно сообщение несколько раз, вам будет проще его обслуживать.
enum UserMessages { case loginSuccess case loginError(_ error: String) func getMessage(withKey key: String = "") -> String { switch self { case .success: return NSLocalizedString("Success!", comment: key) case .error: return NSLocalizedString("An error occurred. Please try again later.", comment: key) } } }
10. Используйте преимущества встроенных функций
Используйте функции, которые уже включены во фреймворк Foundation. Вот некоторые примеры.
var bool = false bool.toggle() // bool = true struct Person { let name: String let age: Int } var array = [Person(name: "John", age: 30), Person(name: "Jane", age: 20), Person(name: "Mike", age: 20)] print(array.map({ $0.name })) // ["John", "Jane", "Mike"] print(array.filter({ $0.age == 30 })) // [{"John", 30}] array.forEach{print($0.name)} // "John" "Jane" "Mike"
Есть ли у вас другие советы, которые вы используете для улучшения качества кода?