Ogni classe che scrivo aderisce ad un'interfaccia?

10

Sto scrivendo un gioco in Typescript, e ho deciso di andare a provare ad aderire all'idea di " programmazione basata sull'interfaccia ", in cui si scrive codice basato su un'interfaccia, anziché sull'implementazione, di un oggetto.

Ho scritto un buon numero di interfacce e classi che le implementano, poi ho fatto un passo indietro e ho capito che le classi erano abbastanza semplici che probabilmente non avrò mai bisogno di cambiare l'implementazione, dal momento che c'è davvero un solo modo per fai ciò che fa la classe (spostando una Phaser.Sprite in un modo limitato per comportarti come un carro armato).

Poi mi ricordo di aver letto alcuni anni fa l'idea di YAGNI , che fondamentalmente non dovresti t sovra-ingegnerizzare il tuo codice per includere cose che potresti non usare mai.

Seguendo le best practice, ogni classe dovrebbe implementare un'interfaccia, o dovrebbe limitarla a classi che si prevede possano essere potenzialmente scambiate in futuro?

    
posta Carcigenicate 02.05.2016 - 20:12
fonte

4 risposte

6

La ragione per avere interfacce è perché semplifica il polimorfismo. Significa che puoi inviare istanze per contratto piuttosto che conoscere la loro effettiva implementazione. Ad esempio, puoi inviare un "Reader" a un metodo, in modo che un metodo chiamato possa utilizzare il suo metodo "read ()". Dichiarando un'interfaccia "Reader" è possibile rendere qualsiasi oggetto conforme a questo contratto, implementando i metodi specificati. In questo modo, qualsiasi chiamante può presumere che esistano determinati metodi, anche se gli oggetti sottostanti al contratto potrebbero essere completamente diversi.

Questo disaccoppia il polimorfismo da una classe base e lo rende possibile anche tra i confini della catena di classe, implicando un contratto.

Ora ... Questo è utile solo se hai bisogno che più catene ereditarie agiscano allo stesso modo, o se avrai molte classi base con un comportamento comune che vorresti passare ad altri utenti.

Se hai solo UNA catena di ereditarietà (classe di base e sottoclasse) o solo la base, o non hai effettivamente bisogno di PASSARE gli oggetti correlati a qualcun altro o di usarli genericamente, allora non aggiungerei implementazioni di interfaccia, come quella nozione è quindi inutile.

    
risposta data 03.05.2016 - 13:01
fonte
6

Se non sei sicuro di aver effettivamente bisogno delle interfacce, probabilmente non lo farai. Questo è il cuore del principio YAGNI. Quando devi essere in grado di scambiare l'implementazione, quindi introduci un'interfaccia.

    
risposta data 02.05.2016 - 20:16
fonte
6

Creare un'interfaccia per ogni classe è un po 'eccessivo. Da una prospettiva puramente orientata agli oggetti, ogni classe ha già un'interfaccia . Un'interfaccia non è altro che i metodi pubblici e i membri di una classe.

Generalmente usiamo "interfaccia" per indicare "una classe Java definita usando la parola chiave interface " o "una classe C ++ con solo funzioni virtuali pubbliche e pure". Queste sono astrazioni utili, perché separano l'interfaccia di una classe dalla sua implementazione.

Con questo in mente, usa le interfacce quando opportuno.

  • Ci saranno più implementazioni per un'interfaccia? Se è così, questa situazione può essere un candidato per l'estrazione di metodi comuni, rivolti al pubblico in un'interfaccia.

  • Consegnerò implementazioni di una potenziale interfaccia ad altri moduli che non dovrebbero conoscere il funzionamento interno del mio modulo? Un'interfaccia può essere utile qui, perché riduce la dimensione del punto di contatto tra i moduli.

Notate le parole di donnola sopra: "può" essere un candidato, "può essere" utile. Non esiste una regola ferrea che dice "sì" o "no" per una determinata situazione.

Detto questo, avere un'interfaccia per tutto è probabilmente eccessivo. Se vedi questo modello, stai andando lontano:

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}
    
risposta data 02.05.2016 - 20:24
fonte
3

Può essere molto allettante per i nuovi sviluppatori pensare alle interfacce come a un inconveniente che si aggiunge semplicemente perché ti viene detto che è "best practice". Se sei ci stai facendo ciecamente, ha un sapore di programmazione settoriale cargo .

Ci sono una serie di ottime ragioni per cui dovresti considerare le interfacce per sviluppi più ampi piuttosto che riunire un insieme di classi.

Strutture di simulazione

Se vuoi provare un'applicazione multistrato senza dover creare oggetti per i vari livelli, ti consigliamo senza dubbio di usare strutture di simulazione per deridere i livelli. Le interfacce sono ampiamente utilizzate qui.

Iniezione di dipendenza

Anche se sono caduti in disgrazia a causa del gonfiarsi che aggiungono, l'idea è sana: la capacità di scambiare semplicemente concrezioni basate su un'interfaccia. Il principio può anche essere trovato in molti modelli di progettazione come il modello di fabbrica.

Questi approcci sono riassunti in D da Principi SOLID . Lo strofinamento di questo è - usa astrazioni, non concrezioni.

Come gli stessi schemi di progettazione, quando usarli è un giudizio. Il punto da tenere in considerazione è capire in che modo le interfacce sono utili e non limitarti ad attaccare le tue lezioni perché ritieni necessario. C'è una buona discussione sui vari meriti di DIP e YAGNI qui .

    
risposta data 03.05.2016 - 12:27
fonte