Dovremmo sempre ASCIUGARE? Qualche esempio di caso limite di quando non farlo? [chiuso]

0

Ho sempre lavorato solo in linguaggi di alto livello come C # e JavaScript.

Un paio di minuti fa qualcuno ha chiesto questa domanda su SO.

Ora sono curioso di sapere, per alcuni dei linguaggi di livello inferiore o in particolare per quelli che non ho incontrato, per il resto ...

Quale sarebbe una situazione valida per non applicare il principio / linea guida ASCIUTTA?

Mi rendo conto che le cose come i test unitari ne sono un esempio, e il link condiviso da @mkk è un eccellente esempio di DRY-over engineering, ma in discussione con uno dei miei colleghi abbiamo tentato di pensare ad alcuni altri solo per una questione di interesse.

    
posta Rohan Büchner 28.04.2015 - 17:31
fonte

5 risposte

5

C'è sempre un momento in cui devi semplicemente violare una regola, anche se tutto ciò che conosci come codificatore dice che deve esserci un altro modo.

Buoni esempi di quando DRY potrebbe non essere la migliore strategia per usare subito il marchio includono:

  • Codice che, per quanto ne sai, è una tantum. In genere ho una regola "three-strikes" per il refactoring; "fallo funzionare, rendilo pulito, rendilo SOLIDO". Se sto scrivendo una riga di codice per fare qualcosa, e ho un'altra linea di codice da qualche altra parte che farebbe quella cosa con un aggiustamento qua e là, poi premo Ctrl-C, Ctrl-V e non la do un secondo pensiero. Perché? Perché non vengo pagato per un bel codice, vengo pagato per codice funzionante. Il codice riutilizzabile e di facile manutenzione è a mio vantaggio ed è solo un vantaggio se prevedo di entrare e apportare modifiche. Se non lo faccio, allora finché non mi sono dimostrato sbagliato , le regole di sviluppo di avorio-tower interferiscono solo con un programma di lavoro (e con il mio stipendio). TUTTAVIA , una volta che ho avuto torto, dovendo tornare in quel file di codice e apportare una modifica, devo essere abbastanza disciplinato per tornare indietro e ripulire, pagando il "debito tecnico" "presto invece di combinarlo con più spaghetti.

  • Codice di prova . Questo è un sottoinsieme significativo del punto precedente. Se stai scrivendo un test per una variazione sul comportamento esistente e hai un test che esercita il comportamento preesistente, copia il test. I test sono in genere "scrivi una volta, esegui molti", con pochissima manutenzione necessaria una volta che i test diventano verdi, quindi sono l'esempio perfetto di un pezzo di codice che probabilmente non vedrai mai più. Naturalmente, devi essere ancora abbastanza disciplinato che la prima volta che viene richiesto un cambiamento per entrambi i test (o la quarta della quinta volta che copi lo stesso test per farne un altro), cerchi modi per garantire che ulteriori cambiamenti avvengano in un unico luogo , non due (o sei o dieci o ...).

  • Implementazioni di un'interfaccia o di una classe base astratta . Anche se potresti pensare che questi siano il modo principale per evitare di ripetere te stesso, la verità è che l'impostazione di più classi come implementazioni di alcuni tipi di base comporta un sacco di caratteri molto simili e non tutti di cui è possibile evitare. Ciò è particolarmente vero se la gerarchia segue un modello di Metodo modello in cui una grande funzione di guida in un tipo di base dipende da specifiche nei tipi derivati; se hai dieci classi che implementano questo tipo di base, le probabilità sono buone, almeno due di esse finiranno con la stessa implementazione per uno dei metodi stub. Non abbastanza da giustificare l'implementazione di tale implementazione nella base, ma è un codice ripetuto. Le interfacce, che non possono avere alcun codice, soffrono di implementazioni duplicate quasi per definizione.

Ci sono altri esempi, ma questi sono alcuni di quelli che generalmente incontro. In breve, DRY non è una regola dura e veloce, è solo una di quelle cose che tieni a mente, e quando ripeti te stesso, è un "odore di codice", che indica che potresti incorrere in debiti tecnici o solo in generale rovinare. Quando il tuo codice "sente l'odore", vale la pena dare un'occhiata, ma un odore non è sempre un vero problema, e anche se lo fosse, potrebbe non valere la pena risolverlo (o anche uno che è possibile risolvere).

    
risposta data 28.04.2015 - 18:11
fonte
4

SQL Server. Le funzioni scalari definite dall'utente in una query T-SQL impediscono un piano di esecuzione parallelo e possono avere anche altri effetti negativi sulle prestazioni.

Hugo Kornelis lo spiega bene qui .

...it’s easy to see why using functions to encapsulate and reuse common computations is considered a best practice. But SQL Server isn’t a traditional programming language. It’s a declarative language, with an optimizer that has been designed to optimize the execution order within queries to make sure that the results are returned as fast as possible

    
risposta data 28.04.2015 - 17:50
fonte
2

DRY esiste per un motivo, poiché più posti esiste lo stesso codice, più possibilità ci sono di bug derivanti da uno di quei posti che non vengono modificati quando il sistema deve cambiare. È anche, ovviamente abbastanza, più facile da testare se si dispone di una determinata parte del codice in un unico punto. Di conseguenza, nella maggior parte dei casi in cui ho bisogno di fare qualcosa più di una volta, lo romperò nella sua funzione o metodo.

Un luogo in cui ritengo che la ripetizione sia accettabile, o addirittura utile, è quando si ha lo stesso codice che funziona con intenti diversi, quindi si potrebbe avere una funzione o un metodo che mostra un comportamento molto simile, ma in un punto fa parte di il sistema per il recupero di un utente da un sistema di autenticazione e in un altro sta recuperando alcuni dati da un negozio. Anche se il codice è identico, questo può esistere in luoghi diversi perché fa parte di flussi diversi e con queste intenzioni divergenti è molto probabile che divergano a un certo punto nella funzionalità. Se condividessi il codice a quel punto, dovrei rendere le cose più complesse e meno leggibili.

Detto questo, se ho lo stesso codice o molto simile in più posti che inizia a sentire l'odore di WET per me e certamente penserò se potrei astrarre il comportamento pertinente in un modo che faciliterebbe la condivisione.

    
risposta data 28.04.2015 - 18:38
fonte
2

Quando l'efficienza del runtime è importante, la ripetizione di te stesso (ad esempio cicli di svolgimento) potrebbe essere utile perché alcuni lavori che dovrebbero essere eseguiti in fase di esecuzione vengono eseguiti in precedenza. Idealmente, queste cose dovrebbero essere fatte da un compilatore.

Inoltre, quando lavori con una lingua che non offre quel tipo di genericità che ti consentirebbe di evitare di ripetere te stesso, potrebbe essere necessario duplicare le cose.

Oltre a ciò, segui le due regole di DRY:

  1. Non ripeterti
  2. Vedi 1.
risposta data 28.04.2015 - 19:39
fonte
1

Il problema con i linguaggi di livello inferiore non è che "potrebbe essere una buona idea" non rimanere ASCIUTTI quando si utilizza la lingua specifica. Il problema è che può essere difficile impossibile rimanere SECCHI se la tua lingua manca di alcuni mezzi di astrazione.

Ad esempio, se la tua lingua non fornisce alcun tipo di funzione di ordine superiore (o almeno di puntatore a funzioni), prova ad implementare qualcosa come un generico cercatore di radici riutilizzabile, ad esempio un Newton solver . Se il tuo linguaggio non supporta né i generici né una "classe di oggetti comuni" né una void * , prova ad implementare qualcosa come una lista riutilizzabile.

Per questi esempi, forse l'unica soluzione possibile per implementare un algoritmo o una struttura dati più di una volta, adattata ogni volta alla situazione specifica.

    
risposta data 28.04.2015 - 18:09
fonte

Leggi altre domande sui tag