Per quali ragioni useresti un'estensione di classe separata per ogni delegato in Swift?

12

Stavo lavorando a un tutorial di Ray Wenderlich e ho notato che l'autore utilizza le estensioni di classe per contenere i callback delegati piuttosto che averli gestiti nella classe stessa, vale a dire:

delegare i callback all'interno della classe:

extension LogsViewController : UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        ...
    }
}

anziché essere contenuto nella classe:

delegare i callback all'interno della classe:

class LogsViewController : UITableViewController, UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        ...
    }
}

Ho trovato questo strano e interessante allo stesso tempo. Ha un file dedicato solo alle estensioni della classe LogsViewController denominato "LogsViewControllerExtension.swift" e ha un'estensione diversa per ogni protocollo delegato: UITableViewDataSource, UISplitViewDelegate, ecc. Ad esempio:

più estensioni di classe ciascuna con delegazioni di callback all'interno del proprio file:

extension LogsViewController: UISplitViewControllerDelegate {
    ... callbacks
}

extension LogsViewController : UIPopoverPresentationControllerDelegate {
    ... callbacks
}

Perché?

Quali vantaggi ci sono per fare questo? Posso vedere dove potrebbe essere un po 'più leggibile separarlo ma allo stesso tempo è un livello di riferimento indiretto. Ci sono dei principi OO che sono di supporto o contro questo?

    
posta morbidhawk 03.11.2015 - 19:29
fonte

3 risposte

15

Non so perché hai detto che aggiunge un livello di riferimento indiretto. Forse intendi qualcosa di diverso rispetto al significato tradizionale, perché non c'è nessun riferimento indiretto creato da questo. Ma perché farlo?

Lo faccio perché è più modulare. Tutto il codice richiesto dall'interfaccia è raggruppato in un'unica posizione (eccetto le proprietà effettive). Se in seguito scelgo di creare una classe separata per implementare quel protocollo (e quindi introdurre un livello effettivo di riferimento indiretto), tutto ciò di cui ho bisogno fare è modificare l'estensione in una classe a sé stante (passando le proprietà necessarie attraverso una funzione init) e creare una proprietà sul ViewController per istanziare l'oggetto in.

Metto anche alcune funzioni private che vengono utilizzate solo dalle funzioni di quel protocollo nell'estensione. Non sono arrivato al punto di creare un file completamente separato per l'estensione, ma facendo in modo che sia chiaro che quelle funzioni private sono solo per quel protocollo.

E in ogni caso, le persone si lamentano spesso dei grassi controller di vista e rompendo un controller di visualizzazione in questo modo aiuta a mantenerlo meglio organizzato, anche se in realtà non rende il controller di visualizzazione più sottile.

    
risposta data 02.12.2015 - 04:37
fonte
2

Come ha detto Daniel riguardo ai problemi indiretti, non c'è alcun livello.
Sono d'accordo e vorrei aggiungere una funzionalità extra potente delle estensioni del protocollo che conoscevo di recente.

Supponi di avere un protocollo didCopyText per esempio. Lo implementerai come:

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

In Swift, proprietà e metodi non sono implementati nella dichiarazione Protocollo, si vorrebbe scrivere l'implementazione in ogni classe conforme a didCopyText , con il numero incrementale di classi conformi a questo protocollo con la stessa implementazione, sarebbe finire con solo un codice ripetuto disordinato. Ecco dove le estensioni del protocollo sono utili.

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

Con l'implementazione delle proprietà e del protocollo del protocollo metodi. Ora, qualsiasi classe è conforme a questo protocollo, utilizzerà la stessa implementazione.

    
risposta data 24.04.2017 - 13:11
fonte
1

Supponiamo che la tua classe supporti tre protocolli, e quindi devi aggiungere tre serie di funzioni. L'unico scopo di queste funzioni è supportare un protocollo, quindi è necessaria una certa documentazione.

Tuttavia, se si aggiunge un'estensione per ciascun protocollo e in ciascuna estensione si implementano esattamente le funzioni necessarie per tale protocollo, ciò rende il codice molto più leggibile.

Molto probabilmente non li inserirò in file separati a meno che queste estensioni non siano veramente grandi.

    
risposta data 25.04.2017 - 01:48
fonte