Contrôleur de vue massive - IOS - Solutions

16

Je suis sûr que chaque nouveau développeur iOS a le problème suivant: Les contrôleurs de vue sont très rapidement encombrés de code à des fins diverses, atteignant facilement plus de 500 lignes de code.

Voici à quoi cela ressemble pour deux écrans de base et communs:

1) L'écran du formulaire: entrez la description de l'image ici

2) L'écran du contrôleur de vue de table entrez la description de l'image ici

Jusqu'à présent, j'ai lu deux solutions différentes:

  1. Première solution: https://bendyworks.com/single-responsibility-principle-ios/ . Ceci est basé sur les notifications, il sépare complètement le contrôleur de vue du modèle de vue (Intentions) et réduit ainsi le code dans le contrôleur de vue. Je pense qu'il a l'inconvénient de casser le code, similaire aux structures Go-To. Cela ressemble à ceci: entrez la description de l'image ici

  2. La deuxième solution conserve les mêmes contrôleurs de vue encombrés (les actions des boutons sont exécutées dans VC et ainsi de suite). mais utilise des bibliothèques comme TPKeyboardAvoiding , BlocksKit ou d'autres solutions pour la plupart basées sur des catégories. Avec cette deuxième solution, le code est considérablement réduit, mais le contrôleur de vue a encore beaucoup de responsabilités.

Que pensez-vous de ces solutions? Ce qui est mieux? Y en a t-il un meilleur?

Ravul
la source
5
Je ne peux pas donner une bonne réponse à cause du temps, mais cela devrait vous orienter dans la bonne direction.
Mike D
Mon intention est de collecter autant de bonnes réponses que possible pour enfin surmonter ce problème que tant de nouveaux développeurs ont. Merci pour le lien, si je trouve quelque chose de nouveau, je le posterai sûrement ici.
Ravul
Voici un excellent discours sur la lutte contre les contrôleurs de vue gras par Andy Matuschak https://realm.io/news/andy-matuschak-refactor-mega-controller/
Tomasz Bąk

Réponses:

6

Nous pouvons utiliser MVVM pour résoudre ce problème.

Le modèle Model-View-ViewModel, ou modèle MVVM, comme il est communément appelé, est un modèle de conception d'interface utilisateur. VM prend toute la logique de préparation des données de modèle pour l'interface utilisateur à partir de VC.

Exemple:
Vous avez un objet modèle avec certains champs, vous souhaitez formater certains d'entre eux, faire des calculs et les combiner.

Dans le cas MVC, toute cette logique se trouve dans ViewController.
Dans MVVM, vous déplacez tout cela de VC vers VM.

VM préparera toutes les données pour UI et VC les définit comme ceci.

(en classe VC)

self.descriptionLabel = self.viewModel.textForDescriptionLabel;

Tutoriels et sujets:

kaspartus
la source
3
Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure ici les parties essentielles de la réponse et de fournir le lien de référence.
Bart van Ingen Schenau
Je suis d'accord avec Bart. Si personne d'autre ne publiera un résumé de toutes ces méthodes, j'en ferai une dès que je les comprendrai et les testerai toutes.
Ravul
2
@Ravul mise à jour de la réponse
kaspartus
J'ai voté pour votre réponse et je vous remercie pour cette idée. Je lis juste au sujet de la programmation réactive fonctionnelle et cela semble une bonne idée. Je pense que la réponse à cette question est une énumération, avec quelques avantages, inconvénients et au moins un diagramme conceptuel pour les 4 façons suivantes d'aborder le problème: 1) Cacao réactif 2) KVO 3) Méthode déléguée et 4) Méthode classique de écrire un View Controller. Je l'écrirai dès que je testerai toutes ces méthodes si personne d'autre ne le fait avant moi. Si en attendant je trouve de nouvelles voies, c'est encore mieux.
Ravul
3

J'ai déjà dû démêler du code dans des contrôleurs de vue de grande taille et cela m'a vraiment empêché de naviguer dans le contenu au début. Une chose importante que j'ai réalisée est que la taille du View Controller seul n'était pas une raison suffisante pour séparer les choses. Il y a de la complexité à avoir 1 gros fichier et aussi de la complexité à avoir un tas de petits fichiers. Voici quelques raisons valables de refactoriser pour diviser un contrôleur de vue en parties plus petites:

MVC

Le contrôleur de vue ne devrait pas faire beaucoup plus que d'être la colle de connexion entre la vue et le modèle. Si vous avez beaucoup de code de connexion réseau, de code de manipulation d'image, etc., alors envisagez de les répartir en classes d'assistance.

Contrôles multiples avec View Controller comme source de données

Si vous disposez d'un tas de contrôles à l'écran qui ont votre contrôleur de vue comme source de données, envisagez de les diviser en objets de source de données distincts et de les utiliser comme source de données. Ou vous pouvez également les diviser en contrôleurs de vue distincts (comme si votre contrôleur de vue a une vue de table en plus d'un autre contrôleur, vous pouvez le diviser en sa propre classe de contrôleur de vue de table).

Code en double

Si vous avez exactement le même code dans différents contrôleurs de vue, placez-le dans 1 emplacement partagé. Cela rendra votre code réutilisable et aidera à gérer la complexité.

Voici quelques conseils supplémentaires pour minimiser la complexité de View Controller:

Storyboard au lieu de programmatique

La création d'éléments de vue représente beaucoup de code et le code de géométrie de cadre représente également beaucoup de travail. Si ce n'est déjà fait, envisagez d'utiliser des contraintes de mise en page automatique et de placer autant d'éléments View que possible dans le storyboard.

Code / commentaires inutiles

Assurez-vous également de supprimer le code / les commentaires inutiles. Souvent, un nouveau fichier View Controller est fourni avec des méthodes que vous n'utilisez pas. Si vous n'utilisez pas une méthode comme didReceiveMemoryWarningcelle-ci, vous pouvez la retirer en toute sécurité. De plus, comme le fichier View Controller est si volumineux, il est parfois effrayant de supprimer l'ancien code ou les commentaires. Ne remettez pas ça! Cela ne fait qu'ajouter à la complexité.

Notifications

Pour répondre à votre question sur les notifications: les notifications ne sont pas un Golden Hammer à utiliser avec tout. Je trouve que les notifications sont utiles lorsque plusieurs contrôleurs de vue doivent être mis à jour en même temps en raison d'une action particulière. Soyez prudent avec les notifications, en les surutilisant peut vous causer beaucoup de douleur en essayant de les retrouver.

Korey Hinton
la source
2

Il existe une architecture spéciale qu'ils appellent VIPER (View, Interactor, Presenter, Entity and Routing). Je vais essayer de reprendre ici ce que vous devez savoir:

Vue

  • ce sont des vues factices;
  • contiennent des objets comme UIView, UIViewController, UILabel, etc;
  • attend le contenu du présentateur ;
  • gérer l'interaction utilisateur et la transmettre à la couche Presenter .

Présentateur

  • ne connaît pas les objets d'interface utilisateur;
  • obtenir des entrées de la couche View ;
  • gérer la logique d'affichage (la méthode d'ajout présentera un autre écran);

Acheminement

  • gérer la logique de navigation et les animations de transition;
  • connaît des objets comme UINavigationController, UIWindow, etc;

Donc, ce que je pense que vous allez nettoyer dans votre code:

  • les validations de données seront déplacées vers la couche Presenter ;

  • la navigation se déplacera vers les objets filaires ( couche de routage );

  • divisez votre contrôleur de vue en observant le principe DRY ;

  • Les écrans complexes auront deux ou plusieurs vues et présentateurs.

Vous devriez voir le lien suivant sur l'architecture VIPER http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/

Bonne chance!

orafaelreis
la source
1
Cette architecture fonctionne-t-elle pour les petites applications? On dirait que vous devez créer beaucoup d'objets pour l'introduire dans le projet.
Tomasz Bąk
ouais, je suis d'accord que c'est plus objet que MVC traditionnel mais ça vaut le coup. Vous pouvez voir un exemple simple que j'ai créé cette année github.com/orafaelreis/cascavel Cascavel est comme un projet de base pour initialiser des projets VIPER.
orafaelreis
Excellent! L'architecture VIPER semble conçue exactement pour éviter le problème des contrôleurs de vue massifs.
Christophe