DRY è il nemico della gestione dei progetti software?


83

Uno dei principi più basilari e ampiamente accettati dello sviluppo software è DRY (non ripeterti). È anche chiaro che la maggior parte dei progetti software richiede un qualche tipo di gestione.

Ora quali sono le attività che sono facili da gestire (stima, pianificazione, controllo)? Compiti giusti e ripetitivi, esattamente i compiti che dovrebbero essere evitati secondo DRY.

Quindi, dal punto di vista della gestione del progetto, è bello risolvere un'attività copiando 100 volte il codice esistente e apportando alcuni adattamenti minori a ciascuna copia, come richiesto. In ogni momento, sai esattamente quanto lavoro hai svolto e quanto è rimasto. Tutti i manager ti adoreranno.

Se invece applichi il principio DRY e cerchi di trovare un'astrazione che elimini più o meno il codice duplicato, le cose sono diverse. Di solito ci sono molte possibilità, devi prendere decisioni, fare ricerche, essere creativo. Potresti trovare una soluzione migliore in tempi più brevi, ma potresti anche fallire. Il più delle volte, non puoi davvero dire quanto lavoro è rimasto. Sei il peggior incubo di un project manager.

Certo che sto esagerando, ma c'è ovviamente un dilemma. Le mie domande sono: quali sono i criteri per decidere se uno sviluppatore sta esagerando a SECCO? Come possiamo trovare un buon compromesso? O c'è un modo per superare completamente questo dilemma, non solo trovando un compromesso?

Nota: questa domanda si basa sulla stessa idea della mia precedente, quantità di lavoro di routine nello sviluppo del software e sui suoi effetti sulla stima , ma penso che chiarisca il mio punto, quindi mi dispiace per avermi ripetuto :).


96
Facci sapere come si sentono le tue briciole di gestione del progetto quando arriva il momento di dare la caccia, cambiare e testare qualcosa in tutte e 100 le istanze di copia e incolla. E non dimenticare il tempo aggiuntivo che verrà speso per capire perché finisce perché solo 98 di loro sono stati effettivamente cambiati.
Blrfl

16
D'altra parte, @Blrfl, l'ASCIUGATURA prematura del codice prima che sia chiara una buona astrazione può davvero danneggiare anche la produttività, poiché un'astrazione condivisa è una dipendenza condivisa. Non sono in disaccordo, a proposito, sto solo sottolineando che c'è sicuramente un equilibrio da trovare.
GoatInTheMachine,

16
Il principio che impedisce a DRY di perdere il controllo è il principio YAGNI (non ne avrai bisogno) .
Philipp,

88
Non c'è nessun dilemma. Se il project manager vuole che tu faccia molto lavoro manuale superfluo perché è facile stimarlo, allora la soluzione ovvia è licenziare il project manager.
Jacques B

10
Se ti ripeti, devi ancora fare tutto quel lavoro difficile da stimare , oltre a qualche lavoro extra inutile. In che modo aiuta il progetto?
user253751

Risposte:


134

Sembra che tu presuma che l'obiettivo principale della gestione del progetto sia produrre stime esatte. Questo non è il caso. L'obiettivo primario della gestione dei progetti è lo stesso degli sviluppatori: offrire valore al proprietario del prodotto.

Un prodotto che utilizza molti processi manuali lenti piuttosto che l'automazione potrebbe in teoria essere più facile da stimare (anche se ne dubito), ma non fornisce un rapporto qualità-prezzo al cliente, quindi è semplicemente una cattiva gestione del progetto. Non c'è nessun dilemma.

È noto che la stima dei progetti software è difficile e sono stati scritti numerosi libri e sono stati sviluppati vari processi per gestirlo.

Se l' unico obiettivo del PM fosse produrre stime esatte, sarebbe facile. Riempi le stime con 10X e lascia che gli sviluppatori giochino per il resto se finiscono presto. Questo sarebbe effettivamente meglio del tuo suggerimento di utilizzare il copia-incolla diworkwork per ridurre il tempo, poiché i giochi non ridurranno la manutenibilità del prodotto.

Ma in realtà, il proprietario del prodotto desidera preventivi utili e un prodotto di qualità consegnato nel modo più rapido ed economico possibile. Questi sono gli effettivi vincoli che un PM dovrà percorrere.

In ogni caso, contesto il tuo presupposto che il lavoro manuale ripetitivo sia più prevedibile che automatizzato. Tutta l'esperienza mostra che il lavoro manuale ripetitivo è più soggetto a errori. E se viene rilevato un bug nel codice incollato? Improvvisamente, il costo della correzione di un bug si moltiplica per la quantità di ripetizione, il che fa esplodere l'incertezza.


21
Sono completamente d'accordo con le tue affermazioni qui, ma penso che debba essere notato che ci sono molti pessimi project manager là fuori che preferiscono davvero la prevedibilità rispetto alla velocità o alla qualità. La maggior parte delle persone che non hanno una formazione nella gestione del progetto apprendono ciò che sanno al riguardo da ciò che hanno visto e la mia esperienza è che i project manager che possono gestire l'incertezza in modo calmo e razionale sono pochi e rari.
JimmyJames,

5
@FrankPuffer Sono stato lì. Quanto tempo ci vorrà? Un'opzione qui è di fornire un intervallo. Leggi su PERT in particolare su stime a 3 punti perché dovrebbero già saperlo. Percentuale completata? Questo è il più fastidioso. Prova a ignorarlo, ma se non ricordi che è il tempo percentuale, non la percentuale di righe codificate o altro. Quello che vogliono veramente sapere è quando sarà completato? All'inizio, fai previsioni prudenti su ogni compito e perfeziona mentre procedi. Attendere fino all'ultimo minuto per dirti più tempo farà impazzire le persone.
JimmyJames,

11
Quanto tempo ci vorrà? Sono certo del 60% che possiamo finirlo con x, ma c'è una probabilità del 10% che ci vorrà cinque volte di più.
David,

18
@David: Questo probabilmente farebbe impazzire il PM perché sa per esperienza che questo 10% di probabilità si verifica l'80% delle volte :)
Frank Puffer

7
La realtà è che molti posti vorrebbero rintracciare un progetto nel terreno e riuscire inaspettatamente. I PM sono spesso premiati per avere proiezioni accurate, quindi hanno incentivi perversi. Questo è il problema dell'agente principale .
Slitta,

39

Hai ragione: copia e incolla funziona alla grande, e DRY non ha senso quando il tuo compito è quello di produrre un programma per il quale il modello o la copia copiati non dovranno essere mantenuti o evoluti in futuro. Quando questi due componenti software hanno un ciclo di vita completamente diverso, accoppiandoli insieme refactoring del codice comune in una lib comune che è essa stessa sotto forte sviluppo può effettivamente avere effetti imprevedibili per lo sforzo. D'altra parte, quando si copiano sezioni di codice all'interno di un programma o di un sistema di programma, tutte queste parti avranno generalmente lo stesso ciclo di vita. Illustrerò di seguito cosa significa DRY e project management.

Seriamente, ci sono molti di questi programmi là fuori: ad esempio, l'industria dei videogiochi produce molti programmi che devono essere mantenuti per un breve periodo di alcuni mesi o un anno al massimo, e quando quel tempo è finito, copia-incolla il vecchio codice di un gioco precedente in cui è stato superato il periodo di manutenzione, nella base di codici di un nuovo gioco va benissimo e potrebbe accelerare le cose.

Sfortunatamente, il ciclo di vita della maggior parte dei programmi che ho dovuto affrontare negli ultimi anni è molto diverso da quello. Il 98% dei requisiti o richieste di correzione di bug che mi sono arrivati ​​erano richieste di modificaper i programmi esistenti. E ogni volta che devi cambiare qualcosa in un software esistente, la "gestione del progetto" o la pianificazione funzionano meglio quando i tuoi sforzi di test e debugging sono piuttosto bassi - il che non sarà il caso se cambi qualcosa in un posto, ma a causa della copia logica aziendale superata che dimentichi facilmente che devi cambiare anche una dozzina di altre posizioni nella base di codice. E anche se riesci a trovare tutti quei posti, il tempo per cambiarli tutti (e testare le modifiche) è probabilmente molto più alto come se avessi un solo posto dove cambiare. Quindi anche tu potresti fare una stima accurata per il cambiamento, avendo i costi una dozzina di volte più alti di quanto deve essere può facilmente scontrarsi con il budget del progetto.

TLDR - ogni volta che si sviluppa un programma in cui non è necessaria o responsabilità per la correzione di errori e la manutenzione dell'originale o della copia, sentirsi liberi di copiare. Ma se tu, il tuo team o la tua azienda sei o potresti diventare responsabile, applica DRY ogni volta che puoi.

Esempio

Come addendum, lasciami spiegare cosa significa "correzione e correzione di bug" e come ciò porta a imprevedibilità nella pianificazione, specialmente all'interno di un prodotto, da un esempio reale. In realtà ho visto accadere questo genere di cose nella realtà, probabilmente non con 100 istanze, ma i problemi possono anche iniziare quando hai solo un'istanza duplicata.

Il compito: creare 100 report diversi per un'applicazione, ogni report sembra molto simile, alcune differenze di requisiti tra i report, alcune logiche diverse, ma tutto sommato, non molte differenze.

Lo sviluppatore che ottiene questa attività crea la prima (diciamo che impiega 3 giorni), dopo che alcune modifiche o correzioni di bug minori dovute al controllo qualità e all'ispezione del cliente è terminata, sembra funzionare correttamente. Quindi ha iniziato a creare il rapporto successivo copiando e incollando tutto, quindi il successivo, e per ogni nuovo rapporto ha bisogno di circa 1 giorno in media. Molto prevedibile, a prima vista ...

Ora, dopo che i 100 report sono "pronti", il programma passa alla produzione reale e si verificano alcuni problemi che sono stati trascurati durante il QA. Forse ci sono problemi di prestazioni, forse i rapporti si bloccano su base regolare, forse altre cose non funzionano come previsto. Ora, quando era stato applicato il principio DRY, il 90% di questi problemi poteva essere risolto cambiando la base di codice in un unico posto. Ma a causa dell'approccio copia-incolla, il problema deve essere risolto 100 volte anziché una volta. E a causa delle modifiche già applicate da un report all'altro, lo sviluppatore non può copiare e incollare rapidamente la correzione per il primo report nell'altro 99. Deve esaminare tutti i 100 report, leggerli, tradurre la modifica nella modifica segnalare, testarlo e forse eseguire il debug di ciascuno di essi singolarmente. Per il Primo Ministro, questo inizia a diventare davvero difficile - può ovviamente prendersi il tempo per una correzione di bug "regolare" (diciamo, 3 ore) e moltiplicarlo per 100, ma in realtà, questa è probabilmente una stima sbagliata, alcune delle correzioni potrebbero essere più facile da realizzare rispetto ad altri, altri potrebbero essere più difficili. E anche se questa stima è corretta, avere il debug costa 100 volte più alto del necessario e costerà alla tua azienda un sacco di soldi.

Lo stesso accadrà la prossima volta in cui il cliente chiederà di cambiare il colore dell'emblema della sua azienda in tutti quei rapporti, di rendere configurabile la dimensione della pagina o di qualche altro nuovo requisito che influisca su tutti i rapporti in modo simile. Quindi, in tal caso, è possibile effettuare una stima dei costi e fatturare al cliente 100 volte il prezzo che dovrebbe pagare quando il codice fosse stato ASCIUTTO. Tuttavia, provalo alcune volte e il cliente annullerà il progetto perché probabilmente non sarà disposto a pagare i tuoi esorbitanti costi di evoluzione. E forse a quel punto qualcuno farà la domanda sul perché ciò sia accaduto e indicherà con il dito la persona che ha preso la decisione per questa programmazione copia-incolla.

Il mio punto è: quando produci software per gli altri, hai sempre almeno per un breve periodo di tempo la responsabilità di far funzionare la cosa, correggere bug, adattare il programma ai mutevoli requisiti ecc. Anche in un progetto green-field, questi le parti possono rapidamente aggiungere molto di più rispetto allo sforzo di sviluppo inizialmente previsto. E soprattutto quando tutto il tuo codice incollato è all'interno di un prodotto, il periodo di responsabilità è uguale per tutte le parti, il che è abbastanza diverso dalla situazione in cui hai incollato del codice precedente da un progetto morto che non è più sotto manutenzione attiva.


4
Probabilmente una buona risposta ma troppo prolissa rispetto ad altre buone risposte.
Vince O'Sullivan,

4
È possibile ignorare DRY quando "la copia non dovrà essere mantenuta o evoluta in futuro", ma il codice che non verrà mai più utilizzato finisce spesso per essere utilizzato nuovamente.
Andy Lester,

"copia-incolla funziona alla grande ..." - non sono d'accordo! Anche se il programma è unico e garantito per non evolversi mai oltre la versione iniziale, il codice copia-incolla rende ancora più lavoro e rischi per correggere i bug rilevati durante lo sviluppo della versione iniziale del programma. A meno che tu non commetta mai errori, nel qual caso sei un Dio.
Jacques B

1
@JacquesB: dovresti leggere la mia risposta più attentamente, non ho scritto qualcosa di diverso.
Doc Brown,

La programmazione per computer è semplicemente diversa dalla costruzione di macchine identiche con una catena di montaggio. Huh. Chi l'avrebbe mai provato? Forse dovremmo avere programmatori che lavorano come PM. Ma poi avremmo bisogno di programmatori come gestori. Programmatori come azionisti. Programmatori come i clienti ... Spara, basta insegnare a tutti come programmare e come farlo. (In altre parole: i non esperti non capiranno mai le vicissitudini conosciute dagli esperti.)

19

Quindi, dal punto di vista della gestione del progetto, è bello risolvere un'attività copiando 100 volte il codice esistente e apportando alcuni adattamenti minori a ciascuna copia, come richiesto. In ogni momento, sai esattamente quanto lavoro hai svolto e quanto è rimasto. Tutti i manager ti adoreranno.

L'asserzione di base non è corretta.

La cosa che rende il software diverso dalle altre professioni è che stai facendo qualcosa di nuovo ogni giorno. Dopo tutto, nessun cliente sta andando a pagare voi per costruire qualcosa che qualcun altro ha già fatto. Ai project manager potrebbe piacere la prevedibilità, ma ai loro capi piace il valore . Se stai semplicemente incollando il codice con lievi variazioni, non stai fornendo molto valore per l'azienda.

Alla fine la società realizzerà di poter fare lo stesso lavoro in una frazione del tempo assumendo un buon programmatore. E se non lo fanno, lo faranno i loro concorrenti.


2
Direi che la maggior parte delle professioni di ingegneria riguarda "fare qualcosa di nuovo ogni giorno"
BlueRaja - Danny Pflughoeft

12
@ BlueRaja-DannyPflughoeft: Non proprio. Avendo lavorato come ingegnere elettronico / elettrico, posso testimoniare che la maggior parte delle professioni ingegneristiche su larga scala (quei progetti che richiedono una messa in servizio come la costruzione di navi e centrali elettriche) riguardano la sicurezza delle persone che fanno qualcosa di provato e testato. Questo è ciò che le imprese considerano "ingegneria". Fare qualcosa di nuovo è "R&S"
slebetman,

3
@slebetman Forse non hai notato tutto il lavoro svolto dalla tua direzione; anche quando fai sempre la stessa cosa, l'ambiente cambia ogni volta: non hai un modello di una centrale elettrica che puoi semplicemente consegnare a un cliente e che hai finito con esso, devi fare un sondaggio, capire come rifornire l'impianto di materie prime e riportare indietro il prodotto, gestire tutte le materie prime per la costruzione e gestire i problemi di approvvigionamento e carenza di lavoro e un milione di altre cose. E sembra come il lavoro di modello (come molti sforzi di software fanno), ma in realtà non è.
Luaan,

1
@Luaan: Sì, ma niente di tutto ciò sta facendo qualcosa di nuovo. Tutti loro "stanno facendo qualcosa che sappiamo come fare". Lo sviluppo del software è diverso. Principalmente perché nel software, a differenza dei progetti di ingegneria fisica, tendiamo a incapsulare cose che già sappiamo fare nelle biblioteche, quindi non dobbiamo "fare il rilevamento" manualmente ecc. Dovremmo semplicemente importare una libreria per quello e usarla .
Slebetman,

2
@slebetman Quasi tutto il software in fase di scrittura è "qualcosa che sappiamo come fare". Le biblioteche vivono anche in un ambiente che cambia sempre. E tu non hai il 100% di conoscenza ed esperienza con l'intera libreria e tutte le dipendenze di quella libreria e delle altre dipendenze che hai, e ci sono molti sistemi e configurazioni hardware bizzarri che semplicemente rifiutano di funzionare come dovrebbe fare un sistema ragionevole lavoro. L'incapsulamento è eccezionale, ma è comunque costoso e ha bisogno di moltissime indagini. E anche l'ingegneria ha incapsulamento - blocchi prefabbricati, circuiti integrati ecc.
Luaan,

12

La programmazione taglia e incolla alla fine porta a software abbandonato. Ero un appaltatore di un sistema per ordinare servizi di telefonia mobile da una grande compagnia telefonica. Il sistema è stato tagliato e incollato alla nausea perché tutti i test erano manuali e non volevano cambiare alcun codice funzionante. Il più piccolo miglioramento potrebbe comportare una nuova copia di centinaia di righe di codice. Inizialmente l'applicazione era stata scritta per gestire account con un massimo di dodici righe fisiche. Ovviamente questa limitazione è stata fatta in centinaia di posizioni nel codice. Dopo circa quattro anni gli affari hanno chiesto al team cosa ci sarebbe voluto per gestire account più grandi. Hanno stimato circa $ 18 milioni. A quel punto il progetto è stato consegnato a un team offshore per una manutenzione minima. La squadra esistente è stata licenziata.

Le organizzazioni che la pensano in questo modo vengono schiacciate dalle aziende con una tecnologia migliore.


Pensa che sia un cervello migliore, piuttosto che una migliore tecnologia. La tecnologia viene dal cervello, giusto? Cosa è successo a "Pensa in modo più intelligente, non più difficile"?

10

Una massima spesso dimenticata che si applica qui è la regola di 3 . Questo afferma che è OK copiare il codice una volta, ma oltre a ciò dovrebbe essere sostituito da un codice generico.

3 potrebbe sembrare un numero arbitrario ma uno scenario comune è quello in cui i dati e la logica sono duplicati in un'applicazione e in un database. Un esempio spesso citato è dove c'è una tabella di ricerca nel database e un lato client di enumerazione. La differenza nei paradigmi non consente che questo sia facilmente memorizzato in un unico posto e quindi le informazioni appaiono spesso in entrambi i posti.

Mentre è bello avere un codice DRY, ci possono essere momenti in cui la logica aziendale detta un'eccezione e quindi è necessario creare due o più bit di codice dall'origine che in precedenza era generica.

Quindi che si fa? Codice per lo status quo (dopo tutto, YAGNI ). Mentre il codice dovrebbe essere scritto per facilitare le modifiche, scrivere un'intera serie di campane e fischietti per qualcosa che potrebbe non essere necessario è solo bruciare soldi.


6
Nota che questo significa che dovresti commentare che hai copiato il codice (in entrambi i posti) in modo da sapere se stai per copiarlo di nuovo, non dovresti!
Mark Hurd,

3
L'ho fatto in un caso in cui due classi avevano bisogno dello stesso metodo ma erano a malapena correlate - un po 'come cugini lontani. Avrei dovuto aggiungere dipendenze a quasi una dozzina di classi per farle effettivamente condividere il codice. Quindi mi è piaciuto quello che Mark ha suggerito: copia e incolla il metodo e ha anche lasciato un grande, ovvio commento che ha indicato l'altra posizione per quel metodo.
Jeutnarg,

@MarkHurd Yep - ottimo punto ...
Robbie Dee,

8

Nella tua domanda, elenchi solo tre funzioni di gestione del progetto: stima, pianificazione e controllo. La gestione del progetto riguarda il raggiungimento degli obiettivi entro i limiti del progetto. I metodi utilizzati per raggiungere gli obiettivi nei limiti di un progetto sono diversi per i progetti software rispetto a molti altri tipi di progetti. Ad esempio, si desidera che i processi di produzione siano altamente ripetibili e ben compresi. Tuttavia, lo sviluppo del software è principalmente un lavoro di conoscenza- è non routinario e richiede pensiero piuttosto che seguire rigide istruzioni e procedure. Le tecniche utilizzate per avviare, pianificare, eseguire, monitorare e controllare e chiudere un progetto software dovranno tenere conto del tipo di lavoro che deve essere fatto su un progetto software - in particolare, lavoro non di routine che non può essere fatto alle istruzioni e procedure specifiche.

Penso che l'altro problema sia che stai prendendo DRY, un concetto che si riferisce alla ripetizione delle informazioni e cerchi di applicarle alla gestione delle attività. DRY dice semplicemente che dovresti avere una sola rappresentazione autorevole di informazioni. I project manager dovrebbero abbracciarlo, poiché significa che tutti sapranno dove andare per le informazioni, comunicare i cambiamenti sarà facile e i cambiamenti potranno essere controllati e gestiti bene. DRY, attraverso pezzi riutilizzabili, aiuta a contenere i costi a lungo termine, aiuta a mantenere i programmi a lungo termine e a migliorare la qualità: tre pezzi nel triangolo di gestione del progetto . Ci vuole un certo investimento di tempo e denaro speso per rendere le cose ESSENZIALI efficaci, ma il compito del project manager è quello di fare un compromesso di tempo, costi, pianificazione e qualità.


Certo, lo sviluppo del software è un lavoro di conoscenza. In realtà non considererei nemmeno il mio primo esempio (copia / incolla) come sviluppo software in senso stretto. Tuttavia, gestire questo tipo di lavoro è molto più difficile, quindi il Primo Ministro, anche se ha un background di sviluppo e sa tutto questo, nel suo ruolo di Primo Ministro tende a ignorarlo. (Non dico che questa è una buona cosa, è proprio quello che ho osservato molte volte. Inoltre, non penso che quei PM siano stupidi o incompetenti. È più come il ruolo che a volte li costringe ad agire in questo modo. )
Frank Puffer,

3
@FrankPuffer Non sono d'accordo sul fatto che il ruolo di project manager costringa la persona a prendere decisioni particolari. È più probabile una forza educativa o organizzativa. Da quello che ho visto, la maggior parte dell'educazione alla gestione dei progetti si concentra su tecniche di gestione dei progetti più tradizionali (probabilmente perché sono più comunemente applicabili a più progetti) rispetto alle tecniche di gestione dei progetti software. Ciò può diffondersi nelle organizzazioni che si aspettano questo e non guardare ad altre tecniche per la gestione di progetti di knowledge work come lo sviluppo di software.
Thomas Owens

2
@FrankPuffer Certo, è più duro, ma offre più valore. Se il capo del tuo capo è abbastanza intelligente, si sbarazzerà del manager che cerca di "rendere le cose più facili per se stesso" e troverà qualcuno che può effettivamente fare il suo lavoro. Non fraintendetemi, se rendere le cose più semplici fornisce valore, provatelo - ma in ciò che descrivete, questo è quasi certamente a scapito del valore finale.
Luaan,

4

La scrittura di nuovo codice è solo una piccola parte dell'attività

Il tuo suggerimento semplificherebbe la stima della parte di scrittura iniziale del nuovo codice. Tuttavia, per portare effettivamente qualcosa di nuovo (non importa se si tratta di un sistema nuovo di zecca, un'aggiunta di funzionalità o un cambiamento di funzionalità) farlo non è sufficiente ed è solo una minoranza di lavoro - le stime viste in letteratura dicono che in pratica questo parte è qualcosa come il 20% -40% del lavoro totale.

Quindi la maggior parte del lavoro (che include l'adattamento del tuo sviluppo iniziale a ciò che era effettivamente necessario, l'integrazione, i test, la riscrittura, i test) non diventa più facile da stimare; viceversa, evitando intenzionalmente DRY ha appena reso quella parte molto più grande, più difficile e con stime più variabili - quell'errore o necessità di cambiamento che richiede la modifica di tutte le parti clonate potrebbe non accadere, ma se lo fa, allora le tue stime saranno totalmente sbagliati.

Non si ottengono stime migliori migliorando la qualità della stima di una piccola parte del lavoro ma peggiorando la maggior parte del lavoro; quindi non è davvero un compromesso, ma una situazione perdente in cui si ottiene una produttività peggiore ma anche stime peggiori.


È un buon punto. Tuttavia, DRY o principi simili si applicano anche ad altre attività come test o integrazione. Molte cose possono essere fatte in modo meccanico, senza pensare troppo o in modi più intelligenti. Le soluzioni intelligenti sono spesso molto più veloci ma comportano un rischio di fallimento. Inoltre, devi dedicarti a una buona dose di lavoro prima di ottenere qualsiasi risultato.
Frank Puffer,

Non esiste un "rischio di fallimento", esiste una certezza di fallimento. Tutto fallirà prima o poi. Stai solo scegliendo quanto costa il carro funebre e quanto velocemente guidi.

4

DRY è utile ma è anche sopravvalutato. Alcune persone possono andare troppo lontano. Ciò che molti sviluppatori non riescono a capire è che ogni volta che si implementa DRY per utilizzare lo stesso metodo per due (leggermente) scopi diversi, si sta introducendo una sorta di accoppiamento molto stretto tra i diversi usi. Ora ogni volta che si modifica il codice per il primo caso d'uso, è necessario verificare anche se regredisce nel secondo caso d'uso. Se si tratta di casi d'uso ampiamente indipendenti, è molto discutibile se debbano essere strettamente accoppiati - probabilmente non dovrebbero esserlo.

L'uso eccessivo di DRY può anche portare a metodi divini che esplodono in complessità per gestire tutti i diversi casi d'uso in cui sono posti, quando metodi atomici generalmente più piccoli che replicano un po 'di codice sarebbero molto più mantenibili.

Tuttavia, suggerirei che la domanda non è realmente pertinente a livello di gestione del progetto. Un project manager non vorrà davvero preoccuparsi di questo livello di dettagli di implementazione. Se lo sono, probabilmente è una micro-gestione. Davvero ... come vengono implementate le cose è più responsabilità dello sviluppatore e responsabile tecnico. Il project management è più interessato a ciò che viene fatto e quando .

MODIFICA: per commento, concordo tuttavia sul fatto che, nel rendere più semplice la stima dei tempi di sviluppo, evitare la DEUMINAZIONE a volte può ridurre la quantità di incertezza. Ma credo che questa sia una questione insignificante in relazione alle domande più urgenti di (1) per quanto tempo fino al soddisfacimento dei requisiti aziendali, (2) quale debito tecnico viene preso in considerazione nel processo e (3) rischi per il costo totale di la proprietà delle scelte architettoniche fatte - se andare in SECCO o meno in molti casi è una scelta progettuale che dovrebbe essere basata più sul rischio / rendimento di quei fattori, piuttosto che sul rendere un po 'più facile fornire ai project manager informazioni più accurate .


Naturalmente il project manager non dovrebbe occuparsi dei dettagli di implementazione. Non è questo il punto. Il mio punto è che, a seconda del modo in cui uno sviluppatore implementa qualcosa, è più o meno in grado di fornire le informazioni richieste per la gestione del progetto.
Frank Puffer,

Non ha senso per me danneggiare / limitare il prodotto o creare un debito tecnico semplicemente per poterlo riferire meglio. Il valore del rapporto deve sicuramente essere ordini di grandezza inferiori al valore di un lavoro di qualità. Ma YMMV
Brad Thomas,

Forse ai programmatori dovrebbero essere pagati ordini di grandezza più dei manager?

2

Penso che tu stia fraintendendo DRY.

Facciamo un esempio:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

vs.

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

Sostituendo la classe B con C abbiamo seguito il principio DRY e ridotto la duplicazione del codice. Ma non abbiamo aumentato le incognite o il rischio per il progetto (a meno che tu non abbia mai fatto l'eredità prima).

Penso che cosa intendi quando parli di DRY è qualcosa di più simile a un'attività di progettazione. Vale a dire:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!! Nuovo requisito! Alcuni clienti devono essere in grado di moltiplicare i doppi !!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

vs.

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

Qui (supponendo che funzioni) abbiamo progettato una soluzione in grado di gestire sia il vecchio che il nuovo requisito, essenzialmente cercando di creare un modello matematico del problema della vita reale o delle regole aziendali. Nella vita reale il sistema che stiamo modellando sarà ovviamente molto più complicato, il nostro modello non si adatterà esattamente e i casi limite e i risultati inaspettati richiederanno tempo per trovare e correggere.

Quindi, dovremmo prendere B o A versione 2 in questo caso?

  • B sarà più specifico dell'effettiva modifica richiesta con meno effetti collaterali e sarà più facile da stimare e più rapido da fare.

  • Una versione 2 comporterà una riduzione del codice complessivo e sarà la soluzione più elegante

Ancora una volta dirò che dipende dalla qualità delle specifiche e dei requisiti.

Se disponiamo di specifiche molto chiare che coprono i casi limite e la compatibilità con le versioni precedenti, allora possiamo essere sicuri di comprendere il sistema abbastanza bene da riformattare il modello senza produrre bug.

Se abbiamo una richiesta di emergenza per un singolo cliente in cui l'unico requisito è che il comportamento cambi per quel cliente senza considerare l'intero sistema; quindi 'migliorare' il modello refactoring A comporta un rischio sostanziale. Sia di rompere gli altri clienti o di superare la scadenza a causa del tempo extra sconosciuto necessario per progettare e testare la soluzione.


7
Non sono d'accordo L'ereditarietà non è qualcosa che fai una volta e poi la padroni. Ci sono molte insidie. Ci sono ragioni per cui la composizione dovrebbe essere preferita rispetto all'eredità. Quindi dobbiamo prendere una decisione: l'ereditarietà? Composizione? Qualcos'altro? Questa decisione sarà probabilmente difficile nel mondo reale. Nel secondo esempio ci sono anche molte alternative. Che dire di generici / modelli? Il minerale forse ha un approccio funzionale usando lambda? Ancora: molte possibilità ognuna delle quali avrà implicazioni specifiche.
Frank Puffer,

4
Il punto è nel primo esempio che letteralmente rimuovi il codice duplicato con qualunque metodo. ma lo stesso codice esatto viene eseguito in entrambi i modi. Quindi non vi è alcun cambio di funzionalità. Nel secondo esempio cambi l'approccio a qualcosa che speri sia funzionalmente efficace, ma in realtà è un codice diverso
Ewan

1
Ero in una situazione in cui la tua "richiesta di emergenza" era la norma. La società per cui ho lavorato ha creato sistemi di dati personalizzati per molti clienti diversi. Inizialmente hanno creato un sistema con Cobol, quindi lo hanno copiato per il cliente successivo, ecc., Fino a quando non hanno avuto 100 clienti. Ora avevano un lavoro nelle loro mani cercando di apportare miglioramenti e aggiornamenti sistematici. Stavo lavorando su un sistema in grado di replicare il comportamento della maggior parte di questi sistemi, utilizzando un singolo set di codice sorgente, ma personalizzazioni archiviate nei dati di configurazione. Non abbiamo potuto fare tutto e non è stato possibile aggiungere alcune cose.

1

Paragrafo per paragrafo

Uno dei principi più basilari e ampiamente accettati dello sviluppo software è DRY (non ripeterti). È anche chiaro che la maggior parte dei progetti software richiede un qualche tipo di gestione.

Corretta.

Ora quali sono le attività che sono facili da gestire (stima, pianificazione, controllo)? Compiti giusti e ripetitivi, esattamente i compiti che dovrebbero essere evitati secondo DRY.

Le attività ripetitive dovrebbero essere automatizzate, obbligatorie . Sono noiosi, soggetti a errori, se fatti a mano.

Quindi, dal punto di vista della gestione del progetto, è bello risolvere un'attività copiando 100 volte il codice esistente e apportando alcuni adattamenti minori a ciascuna copia, come richiesto. In ogni momento, sai esattamente quanto lavoro hai svolto e quanto è rimasto. Tutti i manager ti adoreranno.

Penso che tu possa cambiare la parola "adattamento" con "configurazione". Considera di avere un bug in questo pezzo di codice che dovrebbe essere copiato. Un bug che appare in condizioni specifiche. Se non è stato risolto nella fonte originale ed è stato copiato, ci saranno molti posti da correggere. Questo può essere negativo, ma poi qualcuno deve:

  • per prima cosa correggi il codice nel sorgente originale;
  • ripari il codice in ogni altro posto;
  • assicurati che quelli fossero tutti i posti. Quando dici che questo deve essere fatto al manager, probabilmente odierà qualcuno.

Se invece applichi il principio DRY e cerchi di trovare un'astrazione che elimini più o meno il codice duplicato, le cose sono diverse. Di solito ci sono molte possibilità, devi prendere decisioni, fare ricerche, essere creativo. Potresti trovare una soluzione migliore in tempi più brevi, ma potresti anche fallire. Il più delle volte, non puoi davvero dire quanto lavoro è rimasto. Sei il peggior incubo di un project manager.

La rimozione di duplicati porta a un singolo punto di errore. Se qualcosa non riesce puoi essere abbastanza sicuro di dove questo accada. I motivi SOLID e Design sono lì per aiutarti a risolvere esattamente quel problema. Scadenze troppo brevi tendono a provocare una "codifica" dello stile procedurale. Più tempo investito in un progetto per creare qualcosa di riutilizzabile significa che dovrebbe esserci una quantità minima di tempo trascorso nel progetto successivo quando la funzione verrà riutilizzata, ma dovrebbe essere configurabile in primo luogo.

Certo che sto esagerando, ma c'è ovviamente un dilemma. Le mie domande sono: quali sono i criteri per decidere se uno sviluppatore sta esagerando a SECCO? Come possiamo trovare un buon compromesso? O c'è un modo per superare completamente questo dilemma, non solo trovando un compromesso?

Molte persone hanno indicato che qui non c'è nessun dilemma. Sì e no.

Se hai qualcosa di altamente sperimentale che non hai mai fatto prima, non c'è nessun dilemma. Altrimenti se hai qualcosa che deve essere fatto di nuovo, come il nuovo sistema di prenotazione hai già delle astrazioni, dipende solo da ciò di cui hai bisogno.

Penso che il dilemma sia: dovremmo implementare qualcosa in una funzione, se è improbabile che venga richiesto. Implementare qualcosa quando richiesto. Nessuno ha bisogno di una grande infrastruttura che non verrà utilizzata.


Implementa qualcosa in modo semplice e veloce ora, perché è stato richiesto. Più tardi, quando è necessario un modo complesso, lo sforzo originale non serve a niente, deve ricominciare da capo. Al manager non piace questo. Come se tu avessi detto: "Il tempo trascorso guidando verso ovest era inutile se ora dovessimo andare ad est". Ma andare in giro per il mondo per la prima volta solo per poter andare ad est per tutto è anche tempo perso.

1

non si tratta affatto di progettare per il futuro riutilizzo o del principio YAGNI. Si tratta di ripetere il codice nel pacchetto di lavoro corrente.

Si tratta assolutamente di design. Forse non riutilizzare di per sé, ma comunque progettare.

Quali sono i criteri per decidere se uno sviluppatore sta esagerando a SECCO?

Esperienza e ambiente / situazione esistente. Per un dato problema otterrai un forte senso del Principio del Prado mentre provi maggiori gradi di ASCIUGATURA. Poi all'improvviso vengono in gioco considerazioni sulla gestione. Tempo, obiettivi, cliente, gestione del codice a lungo termine (qualcuno ha detto debito tecnico ), ecc. Informeranno il tuo piano di attacco.

Come possiamo trovare un buon compromesso?

Uh ... design? Il refactoring è design, beh dovrebbe essere. L'ambito del DRYing può facilmente espandersi come una super nova dal loop, al metodo, alle classi. Ci sono stato, l'ho fatto. Ma non puoi davvero saperlo fino a quando non studi il problema: questo è design.

Come può non essere un problema di progettazione? È necessario considerare il problema in modo più ampio rispetto al codice duplicato immediato a portata di mano. Questa è un'attività di progettazione che si tratti di codice esistente o di un foglio bianco; che si tratti del "metodo extract" o della creazione di nuove classi e moduli.

Epilogo

... la domanda sottoposta e le sue risposte non coprono l'aspetto della gestione del progetto.

Gestione tipica, ignorando i tempi di progettazione. Idealmente, avremmo progettato la ripetitività superflua ridondante prima della codifica. Invece, il management pensa che lo sviluppo (e correzioni di bug) sia un singolo evento olimpico - la codifica - quando in realtà è un decathlon. E misurano a 1/1000 di secondo perché pensano che sia tutto analogico.

Se invece applichi il principio DRY e cerchi di trovare un'astrazione che elimini più o meno il codice duplicato, le cose sono diverse.

Ho avuto questa esperienza: "Ho trascorso due giorni a scrivere questa riga (di un modulo GUI) e due ore a scrivere il resto del modulo." Voglio dire che mi sono preso il tempo di identificare le classi riutilizzabili - DRY è un effetto collaterale naturale - la riga del modulo GUI e in quella altre. Una volta eseguito il debug, questi sono stati utilizzati, individualmente e nella composizione, in tutto il modulo che ora ha codificato molto velocemente e i test sono stati eccezionalmente rapidi nonostante la complessità di costruzione. E ha anche superato test formali con una percentuale di bug sorprendentemente bassa.

Il più delle volte, non puoi davvero dire quanto lavoro è rimasto. Sei il peggior incubo di un project manager.

Neanche io lo sapevo, ma credevo che lo sforzo di progettazione iniziale avrebbe dato i suoi frutti. Lo diciamo tutti, ma la direzione in particolare non se ne fida. La direzione avrebbe pensato che stavo scherzando. "Due giorni e non hai nemmeno il 2% di esso ancora codificato!"

In un caso siamo rimasti fedeli alle nostre pistole quando il management ha detto "stai spendendo troppo tempo nel design, vai avanti". E i colleghi che dicono "sono troppe classi". Bene, un sotto-progetto molto meno complesso avrebbe dovuto durare circa 1 mese (pensavo fosse OK ipotesi) ma ci sono voluti 5 mesi. Di questi 3 mesi sono stati testati / riparati perché era un simile POS. "Ma non abbiamo avuto il tempo di progettare!". Lo hanno effettivamente detto.

Le mie domande sono: quali sono i criteri per decidere se uno sviluppatore sta esagerando a SECCO? Come possiamo trovare un buon compromesso? O c'è un modo per superare completamente questo dilemma, non solo trovando un compromesso?

Mostra alla direzione come funziona. Cattura alcuni dati. Confronta con altri lavori, in particolare quello dei tuoi colleghi che svolgono il lavoro precipitoso. Quel mucchio di insuccessi sembra sempre perdere la gara, rimanere bloccati nei test e poi dopo il rilascio è tornato più volte per correggere altri bug.


"Misura con un micrometro, segna con il gesso, taglia con un'ascia."
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.