Le direttive del compilatore sono un antipattern?

4

Sto lavorando su un sistema legacy che ha una classe helper che è collegata simbolicamente a diversi progetti .Net all'interno di una soluzione. La logica è piena di direttive del compilatore che modificano il suo comportamento interno in base al quale viene compilato il progetto .Net. Ad esempio, c'è una direttiva del compilatore che interpone una variabile "HAS_UI" e se è vera, compila in una istanza di frmProgress e visualizza avanzamento all'utente.

Sto cercando di spiegare ai colleghi perché questo è un progetto scadente facendo riferimento a specifici anti-schemi. Tutto quello che posso inventare finora sono i pattern "positivi" che dovevano essere usati, come il Pattern di Responsabilità Unica o il pattern di Osservatore.

Qualcuno può suggerire specifici anti-schemi che potrebbero essere applicati qui?

Thx

    
posta sisdog 11.05.2013 - 00:30
fonte

4 risposte

10

"Dipende"

Le direttive del compilatore possono essere strumenti eccezionalmente utili. Possono fornire regole ironclad che mantengono gli aspetti di sviluppo (debug) accettabili dalle build di produzione (rilascio). Allo stesso modo, un assembly può essere reso più leggero rimuovendo le istruzioni di tracciamento una volta che la build è passata in versione.

D'altra parte, possono essere maltrattati. Una volta ho avuto il dispiacere di aver tirato fuori una API scadente che aveva direttive per 7 o 8 piattaforme diverse oltre a debug & codice ottimizzato. È stato un casino pieno di bug che non si sarebbe potuto compilare nel mio ambiente.

Fai attenzione a non cadere nel tuo anti-pattern di "Non l'ho scritto così quindi è una schifezza". Presumibilmente, il progetto ha avuto almeno una versione e ha tenuto sotto un certo livello di manutenzione. È un anti-pattern per dichiarare il codice come una schifezza semplicemente perché non puoi avvolgerti nella testa.

Per essere chiari, non sto dicendo che quello che sta facendo il tuo progetto è giusto, ma non è necessariamente sbagliato. L'impeto è su di te per capire appieno cosa sta succedendo nel codice e quindi essere in grado di spiegare perché è sbagliato. Gli esempi che hai fornito non sono saltati fuori e urlano "ew, questo è male", quindi ho il sospetto che tu possa avere più ricerca da fare con il codice.

In definitiva, dovresti essere in grado di puntare a specifiche sezioni di codice e dire "questo è sbagliato a causa di XYZ". Non dovresti fare affidamento su anti-schemi colloquiali per dimostrare il tuo caso.

    
risposta data 11.05.2013 - 01:27
fonte
7

Penso che tu stia prendendo questo da un approccio arretrato. Gli anti-schemi sono un modo di nominare cose che hanno caratteristiche cattive: sono malattie, non sintomi. Sono davvero i sintomi a cui teniamo, anche se non abbiamo ancora chiamato questa specifica malattia.

Il modo in cui dovresti parlare di questo è in termini di vizi o difetti funzionali effettivi che questo modo di programmazione ha:

  • È quasi impossibile testare in modo significativo perché il codice dipende dall'ambiente
  • È molto pericoloso apportare modifiche perché devi testare le tue modifiche in così tante diverse condizioni
  • È difficile leggere il codice perché devi conoscere il valore di molti fattori esterni
  • La complessità combinatoria di tutti questi flag crea un numero elevato di configurazioni su cui ragionare
  • Devi ricompilare una grande quantità di codice per vedere se hai rotto qualcosa

E così via.

    
risposta data 11.05.2013 - 00:48
fonte
4

The logic is riddled with compiler directives that change it's internal behavior based on which .Net project it happens to be compiled in.

Le direttive del compilatore non sono il problema, sono solo i mezzi usati per creare il presunto problema. Probabilmente avresti la stessa obiezione se dovessi commentare e disapprovare vari blocchi di codice in base al tipo di target che stai costruendo. Almeno le direttive del compilatore ti permettono di evitarlo.

Quindi, la classe in questione si basa molto sulla compilazione condizionale. La ragione principale per cui questo può diventare un problema è che rende il codice meno chiaro - hai un pezzo di codice che sta cercando di essere otto cose diverse allo stesso tempo. Un modo per ridurre il problema consiste nel creare sottoclassi specifiche della classe in questione e utilizzare le direttive del compilatore solo per selezionare la sottoclasse giusta quando si desidera creare un'istanza della classe. Ciò renderà il codice più facile da capire, ma può essere difficile se i vari target utilizzano ciascuna combinazioni diverse di funzionalità.

    
risposta data 11.05.2013 - 07:30
fonte
2

Non sono sicuro che sia un anti-pattern in quanto tale ma sembrerebbe violare l'SRP.

Ma detto questo, ci sono state probabilmente ottime ragioni per cui lo sviluppatore ha fatto quello che hanno fatto in quel momento.

Nonostante i grandi progressi compiuti nei modelli di progettazione e nelle varie metodologie, l'entropia del software continuerà ad essere una sfortunata caratteristica dei sistemi legacy.

Sarei più preoccupato di come testare una cosa del genere. Vuoi fare un piccolo cambiamento in questo codice e indossare immediatamente pantaloni marroni perché ci sono una miriade di codici che potrebbero influenzare.

    
risposta data 11.05.2013 - 12:40
fonte