¿Por qué razones usaría una extensión de clase separada para cada delegado en Swift?

12

Estaba trabajando en un tutorial de Ray Wenderlich y noté que el autor usa extensiones de clase para retener las devoluciones de llamada de los delegados en lugar de que sean manejadas en la misma clase, es decir:

delegar devoluciones de llamada dentro de la extensión de la 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 {
        ...
    }
}

Encontré esto extraño e interesante al mismo tiempo. Tiene un archivo dedicado solo a las extensiones en la clase LogsViewController llamada "LogsViewControllerExtension.xtift" y tiene una extensión diferente para cada protocolo delegado: UITableViewDataSource, UISplitViewDelegate, etc., es decir,

múltiples extensiones de clase, cada una con delegados de devolución de llamadas 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 separarlo, pero al mismo tiempo es un nivel de direccionamiento indirecto. ¿Hay principios OO que apoyen o estén en contra de hacer esto?

    
pregunta morbidhawk 03.11.2015 - 19:29

3 respuestas

15

No sé por qué dijiste que agrega un nivel de direccionamiento indirecto. Tal vez usted se refiera a algo diferente al significado tradicional, porque no se crea una dirección indirecta adicional al hacer esto. Pero ¿por qué hacerlo?

Lo hago porque es más modular. Todo el código requerido por la interfaz se agrupa en un solo lugar (excepto las propiedades reales). Si más adelante elijo crear una clase separada para implementar ese protocolo (y así introducir un nivel real de direccionamiento indirecto), todo lo que necesito es hacer 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 crear una instancia del objeto.

También puse en la extensión cualquier función privada que solo sea utilizada por las funciones de ese protocolo. No he llegado tan lejos como para crear un archivo completamente separado para la extensión, pero al hacerlo queda 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 gruesa y de romper un controlador de vista de esta manera ayuda a mantenerlo mejor organizado, incluso si realmente no hace que el controlador de vista sea más delgado.

    
respondido por el Daniel T. 02.12.2015 - 04:37
2

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 poderosa de las Extensiones de Protocolo que conocí recientemente.

Digamos que tienes un protocolo didCopyText por ejemplo. Lo implementarás como:

protocol didCopyText {
  var charachtersCount: Int {get}
  func addToClipboardWith(text: String)
}

En Swift, las propiedades y los métodos no se implementan en la declaración del Protocolo, desearía escribir la implementación en cada clase conforme al didCopyText , con un número incremental de clases que cumplen con este protocolo con la misma implementación, Terminar con sólo un código repetido desordenado. Ahí es donde Protocol Extensions es útil.

protocol didCopyText {
var charachtersCount: Int {
    get {
     // implementation
    }
}
func addToClipboardWith(text: String) {
      // implementation
 }
}

Con la implementación de las propiedades del protocolo & metodos Ahora, cualquier clase se ajusta a este protocolo, utilizará la misma implementación.

    
respondido por el MEnnabah 24.04.2017 - 13:11
1

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.

    
respondido por el gnasher729 25.04.2017 - 01:48

Lea otras preguntas en las etiquetas