Estaba trabajando en un tutorial de Ray Wenderlich y noté que el autor usa extensiones de clase para retener las devoluciones de llamadas de los delegados en lugar de hacer que se manejen en la clase misma, es decir:
delegar devoluciones de llamada dentro de la extensión de clase:
extension LogsViewController : UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
en lugar de tenerlo dentro de la clase:
delegar devoluciones de llamada dentro de la clase:
class LogsViewController : UITableViewController, UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
Esto me pareció extraño e interesante al mismo tiempo. Tiene un archivo dedicado solo a extensiones en la clase LogsViewController llamado "LogsViewControllerExtension.swift" y tiene una extensión diferente para cada protocolo de delegado: UITableViewDataSource, UISplitViewDelegate, etc.
múltiples extensiones de clase cada una con devoluciones de llamada delegadas dentro de su propio archivo:
extension LogsViewController: UISplitViewControllerDelegate {
... callbacks
}
extension LogsViewController : UIPopoverPresentationControllerDelegate {
... callbacks
}
¿Por qué?
¿Qué ventajas hay para hacer esto? Puedo ver dónde podría ser un poco más legible separar esto, pero al mismo tiempo es un nivel de indirección. ¿Hay principios OO que apoyan o no lo hacen?
fuente
Respuestas:
No sé por qué dijiste que agrega un nivel de indirección. Tal vez te refieres a algo diferente al significado tradicional, porque no hay una indirecta adicional creada al hacer esto. ¿Pero por qué hacerlo?
Lo hago porque es más modular. Todo el código que requiere la interfaz se agrupa en un solo lugar (excepto las propiedades reales). Si luego elijo hacer una clase separada para implementar ese protocolo (y así introducir un nivel real de indirección), todo lo que necesito para do es cambiar la extensión a una clase propia (pasando las propiedades necesarias a través de una función init) y crear una propiedad en el ViewController para instanciar el objeto.
También pongo las funciones privadas que solo son utilizadas por las funciones de ese protocolo en la extensión. No he ido tan lejos como para crear un archivo completamente separado para la extensión, pero al hacerlo deja en claro que esas funciones privadas son solo para ese protocolo.
Y, en cualquier caso, las personas a menudo se quejan de los controladores de vista gordos y romper un controlador de vista de esta manera ayuda a mantenerlo mejor organizado, incluso si en realidad no hace que el controlador de vista sea más delgado.
fuente
Como dijo Daniel con respecto a la indirección, no hay un nivel de ello.
Estoy de acuerdo con él y me gustaría agregar una característica extra potente de Extensiones de Protocolo que conocí recientemente.
Digamos que tienes un protocolo,
didCopyText
por ejemplo. Lo implementará como:En Swift, las propiedades y los métodos no se implementan en la declaración del Protocolo, es recomendable que escriba la implementación en cada clase conforme a
didCopyText
, con un número incremental de clases que se ajustan a este protocolo con la misma implementación, terminaría con solo un desorden código repetido Ahí es donde las Extensiones de protocolo son útiles.Con la implementación de las propiedades y métodos del protocolo. Ahora, cualquier clase que cumpla con este protocolo, usará la misma implementación.
fuente
Digamos que su clase admite tres protocolos y, por lo tanto, debe agregar tres conjuntos de funciones. El único propósito de estas funciones es admitir un protocolo, por lo que necesita documentación.
Sin embargo, si agrega una extensión para cada protocolo, y en cada extensión implementa exactamente las funciones necesarias para ese protocolo, eso hace que su código sea mucho más legible.
Lo más probable es que no los coloque en archivos separados a menos que estas extensiones sean realmente grandes.
fuente