Amélioration de la lisibilité du code dans le développement iOS

Imaginez un livre dans lequel il n'y a pas de division en chapitres, mais tout va sans décomposition logique et sémantique, un livre où il n'y a pas de paragraphes, pas de points et de virgules, un livre où la première ligne raconte une chose, la seconde une autre, la troisième encore première chose.

Présenté?

Pourriez-vous comprendre de quoi parle le livre?

À quelle vitesse pourriez-vous trouver le passage qui vous intéresse?

Votre code, ainsi que le contenu du livre, doivent être structurés de manière à ce que le code soit facile à lire et à en transmettre le sens.

Dans cet article, je vais montrer des exemples d'organisation de code dans lesquels les classes auront la même séquence de blocs principaux et leur répartition.

Pour plus de commodité, j'utiliserai le mot classe (classe), mais j'impliquerai n'importe quel type de type (classe, struct, énum).

Grâce à l'application de ces conseils, votre code deviendra lisible, ce qui à l'avenir lui fournira commodité et rapidité de travail.

Bien sûr, les conseils décrits peuvent être mis à niveau à votre guise, en respectant les principes de base.

Tout d'abord, comparons le même code de deux manières.

Un exemple d'une classe en désordre:


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!
}

Ce code est similaire à un vidage de méthodes, de variables et de sorties, dans lequel tout se confond, il est difficile de comprendre à quoi il se réfère et à quel endroit quoi chercher.

Un exemple de classe pure:


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)
}
}

Ligne vide 38 - indenter une ligne de la dernière méthode afin que vous puissiez voir où se termine le dernier crochet de fermeture de la méthode et où se termine la classe.

La même fonctionnalité est montrée dans les deux exemples, mais la différence est que la deuxième option a une structure claire, grâce à laquelle la logique est plus évidente, le code est facile à lire, vous pouvez trouver rapidement ce que vous recherchez dedans, et en plus, c'est juste agréable de le regarder.

Principes de base pour la formation d'une structure de classe pure:


  1. Utilisez toujours // MARK: -
  2. Donnez les noms des étiquettes et définissez leur priorité
  3. Transformer la logique des méthodes du cycle de vie en méthodes distinctes
  4. Nous utilisons l' extension pour implémenter les protocoles
  5. Sélectionner des éléments logiquement liés
  6. Nous supprimons les inutilisés
  7. Automatiser la routine

1. Utilisez toujours // MARK: -


Pour faciliter la lecture, le livre est divisé en chapitres, et il sera plus confortable pour nous de travailler si nous créons une table des matières en utilisant // MARK: - .

Cette étiquette se démarque non seulement de l'ensemble du code, mais crée également automatiquement une table des matières - elle met en évidence les sections du code en gras dans la liste des éléments de ce fichier.


Vous pouvez afficher la table des matières d'un fichier en cliquant sur le bouton après la flèche droite (>) tout en haut du fichier après le nom de ce fichier ou ctr + 6 (menu des éléments du document).

2. Nous donnons les noms des étiquettes et nous établissons leur séquence


Vous trouverez ci-dessous les principales étiquettes pour diviser le code en blocs connectés logiquement et leur séquence:

// 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

Lorsque vous utilisez cette méthode de regroupement, on peut facilement naviguer dans le code de n'importe quelle classe.

3. Extraire la logique des méthodes du cycle de vie dans des méthodes distinctes


La logique à l'intérieur des méthodes de cycle de vie de ViewController doit être placée dans des méthodes distinctes, même si vous devez créer une méthode avec une ligne de code. Aujourd'hui est un, et demain est dix.

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")
}

Du fait que les détails de mise en œuvre sont externalisés vers des méthodes tierces, la logique du cycle de vie devient plus claire.

4. Utilisez l'extension pour implémenter les protocoles


Sortez l'implémentation du protocole dans l'extension marquée // 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

Cette étiquette contiendra tout ce qui concerne ce protocole - tout ce qui est seulement ici et pas besoin d'aller ailleurs, sinon les méthodes et les propriétés du protocole seront dispersées dans toute la classe.

5. Sélectionnez les éléments logiquement liés


Pour augmenter la visibilité, il est nécessaire de sélectionner des éléments logiquement liés à l'aide d'une ligne vide:

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. Nous supprimons les éléments inutilisés


Ne laissez pas de commentaires inutiles (par défaut), de méthodes vides ou de fonctionnalités mortes - cela obstrue le code. Faites attention à la classe AppDelegate, vous y trouverez probablement des méthodes vides avec des commentaires à l'intérieur.

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. Automatisez la routine


Pour éviter d'écrire manuellement dans chaque classe // MARK: - SomeMark , utilisez l' extrait de code .


Nous écrivons une étiquette, la sélectionnons, puis l'éditeur -> Créer un extrait de code, lui donnons un nom et l'appelons raccourci.

// MARQUE: - Bonus


  1. Marquez la classe avec le mot clé final si cette classe n'a pas d'enfants - le projet se compile plus rapidement et le code s'exécute plus rapidement.
  2. Marquez les propriétés, les points de vente et les méthodes avec le mot-clé privé - ils ne seront disponibles qu'à l'intérieur de la classe et ne seront pas dans la liste publique des propriétés et des méthodes s'ils n'y sont pas nécessaires.


Je vous souhaite plein succès dans le développement d'applications et laissez votre classe devenir plus propre!

// MARQUE: - Aide à la rédaction d'un article
Sergey Pchelyakov
Alexey Pleshkov AlekseyPleshkov

// MARQUE: - Liens
Style de code de Ray Wenderlich

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


All Articles