Cercando di comprendere meglio le interfacce

3

Sto lavorando su un piccolo programma e ho pensato di usarlo come una possibilità per ottenere una migliore comprensione di cose che non ho mai usato prima, principalmente Interfacce ed Eredità dalle classi base.

Fondamentalmente si tratta di un programma di richiesta di utilizzo della struttura e dopo aver effettuato una richiesta è necessario inviare via email al richiedente tutte le informazioni che hanno compilato. Il modulo si suddivide in informazioni sulla richiesta principale (contatto, nome del gruppo, ecc.), Stanze della struttura, struttura e amp; attrezzatura della stanza, date richieste, documento esterno facoltativo. Ho separato ciascuna sezione del modulo nella loro classe personalizzata in modo da poter passare facilmente le informazioni tra i livelli ma quando ho inserito le informazioni nel modello di email ho riscontrato un problema. Le informazioni sulla richiesta e le informazioni sul documento esterno verranno visualizzate solo una volta per richiesta, in modo da poter trovare e sostituire facilmente i segnaposto che ho impostato. Le altre classi tuttavia possono avere più istanze per richiesta. Il modo in cui ho impostato per aggirare questo era questo

Ho creato 2 interfacce

Public Interface SingleInstance
   Public function PlaceHolderReplace() as Hashtable
End Interface
Public Interface MultipleInstances
   Public function PlaceHolderReplace(mi as string 'multiple instance place holder to replace) as string
end Interface

Con queste impostazioni mi sono reso conto che la funzione di sostituzione per ogni classe sarebbe stata la stessa in base al numero di istanze della classe presenti per richiesta, quindi ho deciso di creare 2 classi base che implementano l'interfaccia dall'alto.

Public Class SInstance
Implements SingleInstance
   Public function PlaceHolderReplace() as Hashtable Implements SingleInstance.PlaceHolderReplace
      (code adding placeholder names and class property values to hashtable)
   End Function
End Class
Public Class MInstance
Implements MultipleInstances
   Public function PlaceHolderReplace(strPlcHolder as String) as string Implements MultipleInstances.PlaceHolderReplace
      (code to loop through all properties of current class and make changes to supplied string and return string with replacements)
   End Function
End Class

Finora questo sta funzionando, posso combinare ogni serie di classi di istanze singole o multiple in 2 elenchi di interfacce e passarle attraverso le procedure di sostituzione necessarie che ho. Le singole istanze eseguono solo il ciclo di ciascuna tabella di hash restituita e apportano le sostituzioni. La procedura per sostituire tutte le istanze multiple isola tutti i segnaposti e loop di dati ripetuti attraverso tutte le classi nell'interfaccia restituendo una stringa combinata per tutte le istanze della classe specifica. Mentre stavo costruendo questo mi sono imbattuto in diverse domande a cui non potevo davvero rispondere.

  • Questo è davvero il miglior uso delle interfacce? Ha senso per l'ereditarietà perché ogni classe può eseguire una delle due funzioni in modo da creare due classi base e usare semplicemente l'ereditarietà per determinare quale correre ha senso Il problema è che le interfacce sono implementate solo in una classe ciascuna, quindi in realtà esistono solo in modo che io possa mettere le classi che non sono correlate in una lista.

  • influiscono sul rendimento? Con le classi di istanze multiple perché non correlate, inserendole in una singola lista, dovrei controllare la classe corrente e confrontare i segnaposti della proprietà con ciò che è nei ripetitori dei data place per accertarsi che esistano prima di sostituirli. In alternativa, se chiamassi esplicitamente la funzione di ogni classe, dovrei comunque controllare il segnaposto dei dati ripetuti per scoprire quale deve essere eseguito. Il modo in cui l'ho impostato sembra che richiederebbe più tempo perché ogni titolare di dati ripetuto deve scorrere ogni classe dell'elenco anche se non sono correlati.

  • Questo è il modo migliore per testare come funzionano le interfacce? Sarebbe davvero bello avere qualcosa a cui fare riferimento se ho una scoreggia cerebrale. Dal momento che tutto ciò che ottengo è la possibilità di inserire classi non correlate in una singola lista e questo potrebbe influire sulle prestazioni.

Ho potuto vedere come questa configurazione sarebbe d'aiuto quando questo programma ha bisogno di espandersi che mi è stato detto è quasi garantito che succeda, ma se si espanderà non voglio che le prestazioni soffrano a causa del modo in cui l'ho impostato . Qualsiasi aiuto con queste domande sarebbe fantastico, grazie.

    
posta Daniel Whittaker 10.10.2014 - 18:34
fonte

1 risposta

1

Secondo me hai scelto un esempio abbastanza interessante, ma meno tipico, per capire "come funzionano le interfacce". Tuttavia è un caso d'uso valido.

Un'interfaccia serve a molteplici scopi. In primo luogo, si comportano come un contratto tra due parti su come possono interagire insieme, o su come utilizzare un qualche tipo di funzionalità esposta. Ok, per un contratto completo e valido avremmo bisogno di altre cose, ma concentriamoci solo sulla parte del codice. L'interfaccia descrive quali metodi sono disponibili e quali sono i loro argomenti e valori di ritorno. Non è solo per la documentazione, anche strumenti come il compilatore ottengono le informazioni su come impostare le cose correttamente quando viene chiamato un metodo di interfaccia.

Le interfacce sono anche comunemente usate per disaccoppiare le cose , questa è una parte importante e intrinseca della loro natura. L'interfaccia progettata sopra può essere implementata, ad esempio, in tre classi diverse. Queste classi non devono avere un antenato comune, come sarebbe necessario con una normale ereditarietà. Possono essere completamente diversi per natura, possono anche essere implementati utilizzando diversi linguaggi di programmazione (quest'ultimo è diventato meno importante con .NET ma era un punto importante con COM).

Un terzo aspetto è che una determinata classe può implementare più interfacce , ma non deve necessariamente implementarle tutte. Questo è abbastanza utile, ad esempio:

  • Una versione più recente di un'interfaccia (pubblicata) diventa disponibile. I client più vecchi possono ancora utilizzare i vecchi server, i nuovi client chiedono se una determinata interfaccia è supportata o meno e non reagiscono in modo appropriato.

  • Una particolare implementazione solo supporta determinati aspetti di un set di funzionalità (per qualsiasi motivo). Lo stesso qui, il client chiede le interfacce di cui può aver bisogno e reagisce in modo appropriato, a seconda del supporto fornito dal server.

  • Spesso le diverse interfacce servono completamente scopi diversi , quindi sono separate in parti logiche più piccole. Le interfacce più piccole aiutano a rimanere più concentrate su un determinato compito, in genere sono anche molto più facili da gestire e implementare.

  • Il supporto di una particolare interfaccia segnala un tratto specifico . Ad esempio, con C # viene utilizzata l'interfaccia IDisposable per indicare le esigenze di un trattamento di pulizia speciale per rilasciare correttamente una determinata risorsa critica.

Quello che hai fatto sopra è più o meno una variante di quest'ultimo. Fondamentalmente hai elenchi di elementi che implementano l'una o l'altra interfaccia, fornendoti le informazioni sul trattamento appropriato di quell'istanza. Nel tuo caso non è necessario che il set di funzioni comuni sia esposto tramite l'interfaccia, lo esprimi già tramite ereditarietà.

Va bene, tuttavia è possibile migliorare l'approccio inserendo tutte le istanze in un solo List (Of Object) o List (Of IMyBaseInterface) . Per eseguire una query su tutti gli elementi, è necessario eseguire un'iterazione in tale elenco, verificare quale delle due interfacce è supportata da ciascuna voce e reagire in modo appropriato.

Per quanto riguarda l'aspetto delle prestazioni: non sono uno specialista di VB, ma dubito che anche in VB le interfacce di query e i metodi di interfaccia di chiamata costituiranno un collo di bottiglia per le prestazioni, a meno che non facciate un gran numero di tali operazioni rapidamente, ad es. in un ciclo.

    
risposta data 11.10.2014 - 00:52
fonte

Leggi altre domande sui tag