Je travaillais sur un tutoriel Ray Wenderlich et j'ai remarqué que l'auteur utilise des extensions de classe pour contenir les rappels des délégués plutôt que de les faire gérer dans la classe elle-même, c'est-à-dire:
déléguer les rappels à l'intérieur de l'extension de classe:
extension LogsViewController : UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
au lieu de le faire figurer dans la classe:
déléguer les rappels à l'intérieur de la classe:
class LogsViewController : UITableViewController, UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
J'ai trouvé cela étrange et intéressant à la fois. Il a un fichier dédié uniquement aux extensions de la classe LogsViewController nommé "LogsViewControllerExtension.swift" et possède une extension différente pour chaque protocole de délégué: UITableViewDataSource, UISplitViewDelegate, etc. c'est-à-dire:
plusieurs extensions de classe chacune avec des rappels délégués dans son propre fichier:
extension LogsViewController: UISplitViewControllerDelegate {
... callbacks
}
extension LogsViewController : UIPopoverPresentationControllerDelegate {
... callbacks
}
Pourquoi?
Quels avantages y a-t-il à faire cela? Je peux voir où il pourrait être un peu plus lisible de séparer cela, mais en même temps, c'est un niveau d'indirection. Y a-t-il des principes OO qui sont favorables ou défavorables à cela?
la source
Réponses:
Je ne sais pas pourquoi vous avez dit que cela ajoute un niveau d'indirection. Peut-être que vous voulez dire quelque chose de différent par cela que le sens traditionnel, car il n'y a pas d'indirection supplémentaire créée en faisant cela. Mais pourquoi faire ça?
Je le fais car il est plus modulaire. Tout le code requis par l'interface est regroupé en un seul endroit (à l'exception des propriétés réelles.) Si je choisis plus tard de créer une classe distincte pour implémenter ce protocole (et donc d'introduire un niveau réel d'indirection), tout ce dont j'ai besoin faire est de changer l'extension en une classe qui lui est propre (en passant les propriétés nécessaires via une fonction init) et de créer une propriété sur le ViewController pour instancier l'objet dans.
J'ai également mis toutes les fonctions privées qui ne sont utilisées que par les fonctions de ce protocole dans l'extension. Je ne suis pas allé jusqu'à créer un fichier complètement séparé pour l'extension, mais cela montre clairement que ces fonctions privées sont uniquement pour ce protocole.
Et en tout cas, les gens se plaignent souvent des gros contrôleurs de vue et la décomposition d'un contrôleur de vue de cette manière aide à le garder mieux organisé, même si cela ne rend pas réellement le contrôleur de vue plus mince.
la source
Comme Daniel l'a dit à propos de l'indirection, il n'y en a pas.
Je suis d'accord avec lui et je voudrais ajouter une fonctionnalité supplémentaire puissante des extensions de protocole que je connaissais récemment.
Disons que vous avez un protocole
didCopyText
par exemple. Vous implémenterez cela comme:Dans Swift, les propriétés et les méthodes ne sont pas implémentées dans la déclaration de protocole, vous voudriez écrire l'implémentation dans chaque classe conforme à la
didCopyText
, avec un nombre incrémentiel de classes conformes à ce protocole avec la même implémentation, cela finirait avec juste un désordre code répété. C'est là que les extensions de protocole sont utiles.Avec l'implémentation des propriétés et méthodes du protocole. Maintenant, toute classe conforme à ce protocole, utilisera la même implémentation.
la source
Disons que votre classe prend en charge trois protocoles et que vous devez donc ajouter trois ensembles de fonctions. Le seul but de ces fonctions est de prendre en charge un protocole, vous avez donc besoin de documentation.
Cependant, si vous ajoutez une extension pour chaque protocole, et dans chaque extension, vous implémentez exactement les fonctions nécessaires pour ce protocole, cela rend votre code beaucoup plus lisible.
Je ne les mettrais probablement pas dans des fichiers séparés à moins que ces extensions ne soient vraiment grandes.
la source