2009-03-13 10 views
8

Durante il processo di progettazione di nuove funzionalità nel software, quale processo è la migliore praticaIl che viene prima - L'interfaccia o della Classe

  1. progettare l'interfaccia che la classe implementerà.
  2. Scrivere la classe ed estrarre l'interfaccia in un secondo momento.

Se si sta seguendo il percorso del numero 2, quando si decide che è necessaria un'interfaccia?

risposta

16

L'interfaccia viene visualizzata quando è necessario rifattorizzare le funzioni comuni di più classi.

Fino a quando non ci sono più classi con caratteristiche comuni, è difficile prevedere quale dovrebbe essere l'interfaccia.

Una volta che hai alcune classi, è molto, molto più facile capire quale deve essere l'interfaccia, quindi tornare indietro e ridefinire quelle classi per implementare correttamente l'interfaccia appena scoperta.

Alcune persone progettano molte classi sulla carta per capire quali dovrebbero essere le interfacce. Salva il codice reale di refactoring. Invece, devi refactoring il tuo design.

+0

Sì. Ho anche molta più fortuna nell'estrarre "interfacce" (nel senso di Java) dalle classi esistenti piuttosto che progettarle in anticipo. Ma d'altra parte, disegno sempre una classe individuale dall'interno verso l'esterno - conosco l'API prima dell'implementazione. – emk

+0

Dato che lavoro in Python, non ci sono interfacce formali in stile Java. Tuttavia, spesso accade che è necessario elevare alcune funzionalità di alcune classi per identificarle come visibili e importanti, come un'interfaccia Java. –

0

Beh, se si passa alla fase di progettazione, i progetti per l'interfaccia e la classe verranno creati prima della codifica. Destra?

0

In genere, non è necessaria un'interfaccia, a meno che non si abbia in mente diverse classi che la implementeranno. Quindi, l'interfaccia sarebbe venuta prima.

+0

Non stai cercando di dire "Quindi, il CLASS verrà prima?" –

+0

Le classi vengono prima solo nell'estratto generale. –

1

Direi che le interfacce vengono prima, ma vengono fuori mentre si sta sviluppando una particolare classe/metodo. Quando colpisci un punto che sai di avere dipendenza da qualche altra classe/metodo, usa un'interfaccia per aggiungere la dipendenza e continua a scrivere il tuo codice. Quindi torna indietro dopo aver finito di scrivere il componente corrente e creare i componenti che implementano le interfacce necessarie.

1

Tutto dipende dalla situazione ...

Quando si conosce nella progettazione fasi che avrete più classi che hanno lo stesso 'comunanza', ma la loro attuazione sono diversi, quindi l'interfaccia viene prima .

Tuttavia, il software è organico; è in continua evoluzione, quindi posso immaginare che in alcuni casi avrai una classe e dopo un po 'di tempo sarà necessario estrarre un'interfaccia da quella classe.

0

Sarei d'accordo con S. Lott, aggiungendo che il design di un'interfaccia è "scolpito nella pietra" una volta creato.

Solo per questo motivo, un'interfaccia non dovrebbe essere creata finché non si conosce tutto ciò che contiene.

+1

Qualsiasi tipo di API pubblica sarebbe sicuramente "scolpito nella pietra", ma la maggior parte delle interfacce, anche quelle dichiarate "pubbliche" sono utilizzate solo internamente nel progetto e possono essere facilmente modificate in qualsiasi momento. –

+0

Ma come gestireste questo quando progettate un processo completamente nuovo. Non so, ancora, tutti i tipi di utilizzo a cui questo sarà sottoposto. Questo è un lavoro a livello di bozza, prototipo, –

+1

In tal caso, creane prima un'implementazione e, una volta capito tutto ciò che dovrebbe contenere, estrai un'interfaccia da esso. – Powerlord

2

Di solito vado con la seconda opzione. Scrivi una classe ed estrai l'interfaccia più tardi. Di solito il motivo per estrarre un'interfaccia è la necessità di una seconda implementazione di tale interfaccia (spesso come simulazione per il test delle unità)

1

Infine, la fase di progettazione dovrebbe venire prima della fase di implementazione a prescindere. Prima di iniziare a programmare dovresti avere una visione chiara di quali saranno le interazioni tra le tue classi e, auspicabilmente, le tue decisioni sull'interfaccia saranno ovvie.

Tuttavia, se hai già scritto una classe e ora devi refactoring per avere un'interfaccia, tieni presente che l'interfaccia sta semplicemente selezionando un insieme di funzioni/metodi che hanno uno scopo comune che sarà necessario da più di una classe. Se trovi che ci sono alcune funzioni utili con le altre classi necessarie, allora quei metodi sarebbero buoni candidati per un'interfaccia.

Un'altra parte delle interfacce che li rende davvero utili è che se ci sono certe parti della tua classe che non sono private, ma che vuoi nasconderle da certi altri oggetti, in tal caso, puoi prendere le funzioni vuoi esposto, e fagli un'interfaccia.

Non sono d'accordo con chi dice che non si dovrebbe progettare in anticipo. Tutti i programmatori amano immergersi direttamente in esso e, a volte, è necessario eseguire il refactoring, ma una fase di progettazione avanzata consentirà di risparmiare enormi quantità di tempo di refactoring in un secondo momento.

6

domanda di trucco! Il test viene prima di tutto. Quindi l'implementazione per il test, che è una classe che può o non può implementare già un'interfaccia. Parte del passaggio del test può comportare l'estrazione di un'interfaccia da una classe esistente, ma non cercare di indovinare di cosa avrà bisogno l'interfaccia prima di avere qualcosa che richiede quell'interfaccia.

Ti farai impazzire cercando di capirlo prima del tempo - o comunque, ho sempre fatto nei miei giorni pre-TDD. Decidi quali funzionalità richiede la tua app, scrivi un test e lascia che il test guidi ciò che fai del tuo codice.

1

L'interfaccia è la cosa più importante della maggior parte delle classi, dal momento che l'implementazione può essere modificata in qualsiasi momento, ma una volta che qualcosa è stato fornito nell'interfaccia è difficile o impossibile ritrattarlo. Per il resto del progetto, l'interfaccia è ciò che conta e l'implementazione è il problema di qualcun altro.

Idealmente, le caratteristiche principali dell'interfaccia verranno specificate prima di qualsiasi lavoro di implementazione. (È anche una buona idea progettare i test in anticipo.) I dettagli possono essere autorizzati ad evolversi, ma qualsiasi modifica all'interfaccia dovrebbe essere basata su ciò che altre classi e routine hanno bisogno, non artefatti dell'implementazione. L'implementazione dovrebbe sempre essere determinata dall'interfaccia, non viceversa.

(Poiché questa è una domanda indipendente dal linguaggio, presumo che l'"interfaccia" in discussione sia la funzionalità pubblica della classe, piuttosto che la sostituzione di Java per le classi astratte in C++. essere le parti della definizione di classe contrassegnate come "pubbliche")

+0

Grazie per la risposta parentetica. Sto scrivendo in C#, quindi sì, questo per le funzionalità pubbliche della classe. L'ho contrassegnato come indipendente dal linguaggio perché non importa che io scriva in C#, VB (.NET o altro), Java o pseudo-codice. Sto cercando di vedere quando e perché. –

0

La classe dovrebbe venire prima.

Un bel design può essere determinato solo per essere bello in quanto sottoposto al crogiolo del cambiamento. Come fai a sapere se le tue interfacce resistono alla prova del tempo se non sono state forgiate dal codice per cominciare?

3

Sono d'accordo con Brian Guthrie. Il test viene prima, perché guiderà il tuo design. Mentre questo di solito significa finire con una classe concreta (quella che si progetta specificandone il comportamento come una serie di test), le dipendenze saranno comunemente espresse tramite interfacce (per consentire la simulazione e seguire lo dependency inversion principle).

Questo spesso significa che avrai le interfacce prima di avere le classi, ma solo perché hai necessario prima.

-1

Non so quale sia il migliore, ma sono sicuro che la risposta giusta è sempre una di queste due opzioni in tutti i contesti!

0

vorrei gettare in due diversi punti di vista su ciò che le interfacce sono:

  1. un'interfaccia è un'astrazione di un'entità importante nel vostro sistema. È possibile progettare il sistema in base alle interfacce e alle collaborazioni tra di loro.
  2. un'interfaccia è un posto nel sistema in cui è consentita la variazione di implementazione. Le differenze di piattaforma, le librerie di terze parti, ecc. Sono nascoste da un'interfaccia che può essere implementata in modo diverso per diverse configurazioni del software.

Tuttavia in entrambi i casi si progetta per primo, quindi si codifica.

Per un nuovo sistema, mi aspetto che le interfacce candidate vengano identificate per prime, che successivamente verranno implementate dalle classi. Per un sistema esistente, lo sviluppo di un'interfaccia da classi esistenti si verifica quando si scopre di un'importante entità o punto di variazione nel proprio sistema in cui non era importante prima o dove non era necessario fornire un punto di variazione prima.

0

Quale viene prima? La necessità di una funzionalità o l'implementazione di una funzionalità?

Nel mio flusso di lavoro, l'interfaccia viene prima spontaneamente. Se una parte del mio progetto ha bisogno di una nuova funzionalità, è costruita attorno a come voglio usarla, cioè la sua interfaccia. Quindi segue l'implementazione.

In questo modo, l'implementazione contiene solo ciò che è effettivamente necessario e non viene sprecato tempo nel sovrastimolare un pezzo di codice lucido e inutile.

0

Le interfacce si evolvono molto male nel tempo. Ogni volta che cambi l'interfaccia, rompi il contratto. Tutte le classi che implementano l'interfaccia devono essere sottoposte a refactoring. Per rimanere indietro gli sviluppatori compatibili diventano creativi e progettano IFoo2 su IFoo. Questo diventa un incubo di manutenzione nel tempo.

Considerare quanto segue: preferire la definizione delle classi sulle interfacce. Utilizzare le interfacce quando si desidera fornire una gerarchia polimorfica di tipi di valore. Un altro modo di utilizzare le interfacce è ottenere un effetto simile a quello dell'ereditarietà multipla.

Problemi correlati