In Swift, c'è una grande enfasi sulla Protocol Oriented Programming (POP). L'idea principale della POP è progettare l'architettura a partire dai protocolli (interfacce) piuttosto che dalle classi base. I protocolli offrono flessibilità nell'ereditarietà del comportamento attraverso più catene, riducendo il collegamento tra il codice.
Swift consente ai protocolli di avere implementazioni predefinite (attraverso le estensioni), il che facilita il riutilizzo del codice senza la necessità di gerarchie di classi. L'OOP classico si basa sull'ereditarietà tra classi, che è limitata a una sola catena di ereditarietà. La POP è priva di queste limitazioni, permettendo composizione ed estensibilità.
Esempio di codice:
protocol Drivable { func drive() } extension Drivable { func drive() { print("Guidando in avanti!") } } struct Car: Drivable {} let car = Car() car.drive() // Stampa: Guidando in avanti!
È possibile aggiungere una stored property (proprietà memorizzata) in un'estensione di protocollo?
Risposta: No, nelle estensioni dei protocolli non è possibile aggiungere proprietà (stored) memorizzate, solo proprietà (computed) calcolate e metodi. Ad esempio,
// Errore! extension Drivable { var speed: Int = 0 // Errore di compilazione: Le estensioni non possono contenere proprietà memorizzate }
Storia
In un grande progetto, gli sviluppatori cercavano di aggiungere proprietà memorizzate tramite estensioni di protocolli per il tracciamento dello stato. Il codice compilava con errore, costringendo a riprogettare rapidamente l'architettura a metà sprint per utilizzare soluzioni di terze parti con objc_get/setAssociatedObject — il che ha deteriorato la leggibilità del codice.
Storia
Nel progetto era stata implementata una classe base per diversi tipi di entità e si utilizzava l'ereditarietà multipla tramite protocolli. Uno sviluppatore ha confuso il comportamento dell'implementazione predefinita nell'estensione e ha tentato di sovrascrivere quel metodo nella struct, aspettandosi che fosse chiamata l'implementazione nella struct stessa. Alla fine, è stato difficile seguire l'ordine di chiamata dei metodi.
Storia
Durante la scalabilità del modulo, sono stati utilizzati protocolli per separare le responsabilità, ma a causa della mancanza di esperienza con la POP, gli sviluppatori non hanno garantito dipendenze esplicite tra i protocolli. Questo ha portato alla duplicazione del codice e alla comparsa di conflitti di interfaccia durante la fusione di più estensioni in grandi team di sviluppo.