Aumento de la legibilidad del código en el desarrollo de iOS

Imagine un libro en el que no hay división en capítulos, y todo funciona sin un desglose lógico y semántico, un libro donde no hay párrafos, sin puntos y comas, un libro donde la primera línea habla sobre una cosa, la segunda sobre otra, la tercera nuevamente sobre Lo primero

Presentado?

¿Podrías entender de qué trata el libro?

¿Qué tan rápido podría encontrar el pasaje que le interesa?

Su código, así como los contenidos del libro, deben estructurarse para que el código sea fácil de leer y transmita el significado que contiene.

En este artículo mostraré ejemplos de código de organización en el que las clases tendrán la misma secuencia de bloques principales y su desglose.

Por conveniencia, usaré la palabra clase (clase), pero implicaré cualquier tipo de tipo (clase, estructura, enumeración).

Gracias a la aplicación de estos consejos, su código se volverá legible, lo que en el futuro proporcionará comodidad y velocidad de trabajo con él.

Por supuesto, los consejos descritos se pueden actualizar a su gusto, observando los principios básicos.

Primero, comparemos el mismo código de dos maneras.

Un ejemplo de una clase desordenada:


final class MessyViewController: UIViewController {
private let userService = UserService()
var userID: String?
private var userList: [User]?
@IBOutlet private weak var searchBar: UISearchBar!
weak var delegate: SomeDelegate?
@IBAction private func cancelButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
navigationController?.navigationBar.backgroundColor = .red
navigationItem.title = "Some"
}
@IBOutlet private weak var tableView: UITableView!
}

Este código es similar a un volcado de métodos, variables y salidas, en el que todo se fusiona, es difícil entender a qué se refiere y en qué lugar buscar.

Un ejemplo de una clase pura:


final class CleanViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet private weak var searchBar: UISearchBar!
@IBOutlet private weak var tableView: UITableView!
// MARK: - Public Properties
var userID: String?
weak var delegate: SomeDelegate?
// MARK: - Private Properties
private let userService = UserService()
private var userList: [User]?
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
}
// MARK: - Private Methods
private func setupNavigationBar() {
navigationController?.navigationBar.backgroundColor = .red
navigationItem.title = "Some"
}
// MARK: - IBActions
@IBAction private func cancelButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}
}

Línea vacía 38: sangra una línea del último método para que puedas ver dónde termina el último corchete de cierre del método y dónde termina la clase.

La misma funcionalidad se muestra en ambos ejemplos, pero la diferencia es que la segunda opción tiene una estructura clara, debido a que la lógica es más obvia, el código es fácil de leer, puede encontrar rápidamente lo que está buscando en él y, además, es agradable verlo.

Principios básicos para la formación de una estructura de clase pura:


  1. Siempre use // MARK: -
  2. Dé los nombres de las etiquetas y establezca su prioridad.
  3. Poner la lógica de los métodos del ciclo de vida en métodos separados
  4. Usamos extensión para implementar los protocolos
  5. Seleccionar elementos relacionados lógicamente
  6. Eliminamos sin usar
  7. Automatizar rutina

1. Utilice siempre // MARK: -


Para facilitar la lectura, el libro está dividido en capítulos, y nos resultará más cómodo trabajar si creamos una tabla de contenido de clase usando // MARK: - .

Esta etiqueta no solo se destaca bien de todo el código, sino que también crea automáticamente una tabla de contenido: resalta las secciones del código en negrita en la lista de elementos de este archivo.


Puede ver la tabla de contenido de un archivo haciendo clic en el botón después de la flecha derecha (>) en la parte superior del archivo después del nombre de este archivo o ctr + 6 (menú de elementos del documento).

2. Damos nombres de etiquetas y establecemos su secuencia


A continuación se encuentran las etiquetas principales para dividir el código en bloques conectados lógicamente y su secuencia:

// MARK: - IBOutlets
// MARK: - Public Properties
// MARK: - Private Properties
// MARK: - Initializers
// MARK: - Lifecycle
// MARK: - Public Methods
// MARK: - Private Methods
// MARK: - IBActions
view raw MarkList.swift hosted with ❤ by GitHub

Al usar este método de agrupación, uno puede navegar fácilmente en el código de cualquier clase.

3. Extraiga la lógica de los métodos del ciclo de vida en métodos separados


La lógica dentro de los métodos del ciclo de vida de ViewController debe ponerse en métodos separados, incluso si tiene que crear un método con una línea de código. Hoy es uno y mañana son las diez.

NOT Preferred
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.backgroundColor = .red
someButton.layer.cornerRadius = 10
someButton.layer.masksToBounds = true
navigationItem.title = "Some"
print("Some")
}
Preferred
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
setupSomeButton()
printSome()
}
// MARK: - Private Methods
private func setupNavigationBar() {
navigationController?.navigationBar.backgroundColor = .red
navigationItem.title = "Some"
}
private func setupSomeButton() {
someButton.layer.cornerRadius = 10
someButton.layer.masksToBounds = true
}
private func printSome() {
print("Some")
}

Debido al hecho de que los detalles de implementación se subcontratan a métodos de terceros, la lógica del ciclo de vida se vuelve más clara.

4. Use la extensión para implementar protocolos


Saque la implementación del protocolo en la extensión marcada // MARK: - SomeProtocol :

NOT Preferred
final class CleanViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// all methods
}
Preferred
final class CleanViewController: UIViewController {
// class stuff here
}
// MARK: - Table View Data Source
extension CleanViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userList?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
return cell
}
}
view raw extension.swift hosted with ❤ by GitHub

Esta etiqueta contendrá todo lo relacionado con este protocolo: todo lo que solo está aquí y no es necesario ir a ningún otro lado; de lo contrario, los métodos y propiedades del protocolo se distribuirán por toda la clase.

5. Seleccione los elementos relacionados lógicamente


Para aumentar la visibilidad, es necesario seleccionar elementos relacionados lógicamente usando una línea vacía:

NOT Preferred
private func showActivityIndicator(on viewController: UIViewController) {
activityIndicator.center = viewController.view.center
loadingView.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
loadingView.alpha = 0.5
activityIndicator.hidesWhenStopped = true
activityIndicator.style = .whiteLarge
loadingView.center = viewController.view.center
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 15
viewController.view.addSubview(loadingView)
viewController.view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}
Preferred
private func showActivityIndicator(on viewController: UIViewController) {
activityIndicator.center = viewController.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.style = .whiteLarge
loadingView.center = viewController.view.center
loadingView.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
loadingView.alpha = 0.5
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 15
viewController.view.addSubview(loadingView)
viewController.view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}


6. Eliminamos sin usar


No deje comentarios innecesarios (por defecto), métodos vacíos o funcionalidad inactiva; esto obstruye el código. Presta atención a la clase AppDelegate, lo más probable es que encuentres métodos vacíos allí con comentarios dentro.

NOT Preferred
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
//
// func someFunc() {
// print("Some")
// }
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain
//types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits
//the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
Preferred
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
}
view raw AppDelegate.swift hosted with ❤ by GitHub


7. Automatizar la rutina


Para evitar escribir manualmente en cada clase // MARK: - SomeMark , use Code Snippet .


Escribimos una etiqueta, la seleccionamos, luego Editor -> Crear fragmento de código, le damos un nombre y lo llamamos atajo.

// MARCA: - Bonificación


  1. Marque la clase con la palabra clave final si esta clase no tiene hijos: el proyecto se compila más rápido y el código se ejecuta más rápido.
  2. Marque las propiedades, salidas y métodos con la palabra clave privada : estarán disponibles solo dentro de la clase y no estarán en la lista pública de propiedades y métodos si no se necesitan allí.


¡Le deseo mucho éxito en el desarrollo de aplicaciones y deje que su clase se vuelva más limpia!

// MARK: - Ayuda para escribir un artículo
Sergey Pchelyakov
Alexey Pleshkov AlekseyPleshkov

// MARK: - Enlaces
Estilo de código Ray wenderlich

Source: https://habr.com/ru/post/453428/


All Articles