Perché non tutti i metodi sono virtuali o perché non ogni classe ha almeno un'interfaccia?

8

Questa è una domanda più filosofica, che si rivolge alla piattaforma .NET, ma forse è utile anche per altre lingue. Sto facendo molti test unitari e soprattutto quando utilizzo componenti di terze parti con cui spesso lotto. In .NET è un'enorme pretesa per la progettazione di componenti (er) alla scelta del metodo che dovrebbe essere virtuale o meno. Da un lato c'è l'uso dei componenti (ciò che ha senso essere virtuale), dall'altro è la componente mockability . Puoi utilizzare spessori per simulare componenti di terze parti, ma questo porta spesso a problemi di progettazione e complessità. Come posso ricordare, la discussione su come rendere tutti i metodi sia virtuale (JAVA lo ha sin dall'inizio) in .NET riguardava le prestazioni. Ma è ancora il problema? Perché non tutti i metodi in .NET sono virtuali o perché non ogni classe ha almeno un'interfaccia?

    
posta Anton Kalcik 31.05.2016 - 10:31
fonte

2 risposte

8

Come dice Anders , riguarda in parte le prestazioni e in parte il blocco dei progetti mal concepiti per ridurre il portata dei problemi causati in seguito da persone che ereditano ciecamente cose che non sono state progettate per essere ereditate.

Le prestazioni sembrano ovvie - mentre la maggior parte dei metodi non viene notata sull'hardware moderno, un getter virtuale potrebbe causare un notevole successo, anche su hardware moderno che si basa sempre più su istruzioni facilmente predette nella pipeline della CPU.

Ora il motivo per rendere tutto virtuale di default sembra essere guidato da una sola cosa: i framework di testing unitario. Mi sembra che questa sia una cattiva ragione, in cui stiamo modificando il codice per adattarlo al framework piuttosto che progettarlo correttamente.

Forse il problema è con i framework usati qui, dovrebbero migliorare per consentire la sostituzione delle funzioni in fase di esecuzione con shim iniettati piuttosto che costruire codice che faccia questo (con tutti gli hack per aggirare i metodi privati e quelli non virtuali , per non parlare delle funzioni statiche e di terze parti)

Quindi il motivo per cui i metodi non sono virtuali di default è come ha detto Anders, e qualsiasi desiderio di renderli virtuali per adattarsi a qualche strumento di test unitario è mettere il carrello davanti al cavallo, il design corretto supera i vincoli artificiali.

Ora è possibile mitigare tutto ciò usando le interfacce o rielaborando l'intera base di codice per utilizzare componenti (o microservizi) che comunicano tramite il trasferimento di messaggi invece delle chiamate di metodo direttamente collegate. Se si ingrandisce la superficie di un'unità per testare come componente, e tale componente è completamente autonomo, non è necessario avvitarlo con l'unità per testarlo.

    
risposta data 31.05.2016 - 17:49
fonte
6

Nella tua domanda ci sono due elementi, quindi proverò a risolverli a turno:

  1. Perché i metodi .NET non sono virtuali per impostazione predefinita?

    L'ereditarietà, in pratica, ha molti problemi . Quindi, se deve essere usato come parte di un progetto, allora dovrebbe essere attentamente considerato. Rendendo i metodi non virtuali di default, la teoria è che incoraggia lo sviluppatore a pensare all'ereditarietà quando si progetta una classe. Indipendentemente dal fatto che funzioni in pratica è un'altra cosa.

  2. Perché non tutte le classi implementano un'interfaccia?

    Il design scadente è la risposta semplice. Nonostante siano comunemente riconosciute come buone pratiche da molto tempo, purtroppo molte persone non progettano ancora i loro sistemi con DI e TDD in mente.

La combinazione di classi che non sono completamente ereditabili e non vengono facilmente prese in giro crea una "tempesta perfetta" di codice difficile da testare. Fino a quando non raggiungiamo il giorno in cui tutti usano la DI e il principio dell'interfaccia di progettazione, non c'è molto che possa essere fatto per alleviare il dolore.

    
risposta data 31.05.2016 - 11:26
fonte

Leggi altre domande sui tag