Devo pianificare in anticipo, o capire i programmi mentre li sto scrivendo? [duplicare]

52

Stavo pensando oggi al libro di Paul Graham "Hacker e pittori". Più in particolare, questi due paragrafi :

"I was taught in college that one ought to figure out a program completely on paper before even going near a computer. I found that I did not program this way. I found that I liked to program sitting in front of a computer, not a piece of paper. Worse still, instead of patiently writing out a complete program and assuring myself it was correct, I tended to just spew out code that was hopelessly broken, and gradually beat it into shape. Debugging was a kind of final pass where you caught typos and oversights... [It] seemed like programming consisted of debugging.

... As far as I can tell, the way they taught me to program in college was all wrong. You should figure out programs as you're writing them, just as writers and painters and architects do."

È così che viene insegnato nel mio college e sono abbastanza sicuro anche della maggior parte degli altri college. Capisci cosa farà il tuo programma, e poi capirai come farlo, quindi digiti e esegui il debug. A volte si crea una versione base e si aggiungono funzionalità, ma l'idea è che si pensi e poi si digiti.

Questo tipo di ricorda quel capitolo nel libro di Feynman intitolato "Egli risolve le radio pensando!" dove ha camminato intorno a pensare a come la radio potrebbe essere rotta, e poi la fissa. Per me, questo è ciò che riguarda la programmazione: pensare e quindi trovare una soluzione.

Questo è l'approccio prevalente alla codifica? Se è così, perché non più persone semplicemente hackerano e mettono insieme un programma senza avere un'idea preconcetta di come sarà?

Quali sono i vantaggi e gli svantaggi di think & type vs. spew & battere?

    
posta BlackJack 26.12.2011 - 11:17
fonte

15 risposte

69

Questo è un perfetto esempio della fallacia centrale esclusa. Sì, scrivere l'intero programma su carta prima di toccare la tastiera reale è una cattiva idea. Ma questo non fa l'estremo opposto - saltando immediatamente nella codifica e iniziando ad hackerare - una buona idea. In realtà, è anche peggio.

È molto importante capire cosa stai cercando di scrivere prima di iniziare a scriverlo. Quando ho una nuova funzionalità da implementare al lavoro, mi assicuro di avere una specifica che descriva cosa deve essere fatto prima di iniziare. Lo guardo e, se c'è qualcosa che non ha senso, parlo con le persone che hanno scritto le specifiche e ci occupiamo del problema finché non siamo d'accordo. A volte non avevo capito i requisiti e loro potevano mettermi in riga; altre volte i PM non capivano i dettagli tecnici e finivano per modificare le specifiche.

Quasi tutti quelli che hanno fatto questo possono dirti per esperienza personale che è molto più facile risolvere i problemi nelle specifiche piuttosto che trovare un problema nel tuo codice a metà dell'implementazione, strappare tutto e sostituirlo con qualcos'altro Quindi avere un piano per ciò che scrivi prima di iniziare a scrivere il codice è molto, molto importante.

    
risposta data 05.08.2011 - 23:43
fonte
35

Pensi che Michelangelo sia appena salito in cima alla Cappella Sistina e abbia appena iniziato a disegnare? Sono stati fatti dei disegni di prova. Le approvazioni del Papa erano necessarie. C'era un'armatura da costruire. Modelli realizzati per guidare il gruppo di altri artisti. Il restauro è stato ancora più complesso.

Se voglio creare un'applicazione e non devo considerare le preferenze di progettazione nella testa di qualcun altro, posso solo iniziare a scrivere codice. Se percorri la strada sbagliata, cambia idea. Non volevo comunque quella caratteristica.

Lascia che il pittore o lo scrittore siedano in un comitato. "Oh, vai avanti e trasformi il personaggio principale in una donna, se cambiamo idea in seguito ti faremo sapere e WTF, facciamo 20 'di lunghezza invece di 30. Puoi aggiungere un galeone spagnolo con 50 i rematori unici prima di svelare domani? "

    
risposta data 02.08.2011 - 20:09
fonte
21

Penso che si tratti di un equilibrio. È impossibile pensare a tutto prima di dartelo, il che è esattamente il motivo per cui il modello Waterfall è così rotto. Allo stesso tempo, se si pensa troppo poco, si può creare un grande casino quando si superano le prime diverse iterazioni. Dopotutto, non è possibile battere tutto il codice in forma e sarebbe molto spiacevole se non si fosse ignorato un requisito di base nella fase iniziale che richiedesse una riscrittura a metà del progetto.

Nel processo di sviluppo è richiesto un certo numero di iterazioni, che è ciò che trascura Waterfall (presuppone 1 iterazione perfetta). Agile (o l'ampio gruppo di metodologie "Agile-like") a volte trascura che ogni iterazione ha una certa quantità di overhead, e se non si guadagna molto attraverso ogni iterazione, il numero di iterazioni totali aumenterà e l'overhead si sommerà a un costo significativo.

    
risposta data 02.08.2011 - 18:55
fonte
20

La premessa dell'analogia è sbagliata: molti scrittori delineano o almeno pensano a quello che stanno per scrivere prima di iniziare a scrivere, e molti pittori e architetti faranno dozzine di studi e schizzi prima di iniziare il loro vero lavoro ".

Dato che l'analogia è sbagliata, la risposta è sì - i programmatori dovrebbero lavorare come scrittori, pittori e architetti.

    
risposta data 02.08.2011 - 19:12
fonte
9

Ho avuto un compagno di stanza al college che era un doppio esperto d'arte, facendo pittura e web design. Lui e io abbiamo paragonato molto ai nostri flussi di lavoro. Quando dipinge, non si limita a capire il dipinto mentre lo dipinge. C'erano molte cose che poteva fare prima. Per un tipo di pittura a collage potrebbe disegnare uno schizzo. Su un dipinto fotorealistico disegnava le forme principali con la matita e poi dipingeva nei dettagli. Ma se sapeva esattamente cosa voleva in anticipo, non aveva bisogno di questi aiuti. Ha appena dipinto.

Sono sicuro che vedi le similitudini. Usiamo diversi metodi per aiutare a trovare una buona soluzione per un problema. Se non conosciamo bene una tecnologia, modifichiamo un po 'per capire come sarà la soluzione finale. I prodotti più grandi spesso beneficiano di una sessione di progettazione di grandi dimensioni, con i dettagli che verranno compilati in seguito. E a volte sappiamo esattamente cosa è richiesto, quindi lo codifichiamo semplicemente. Non perché siamo pigri, ma perché attraverso l'esperienza e il pensiero non abbiamo bisogno degli strumenti extra.

Alcuni vantaggi nella progettazione in anticipo:

  • Vedi l'immagine completa.
  • È possibile scorrere tra diversi progetti senza l'impegno di alcuno. Se hai già scritto il codice, non puoi modificare le indicazioni su larga scala.

I vantaggi di saltare nel codice:

  • A livello micro hai la possibilità di provare molte cose velocemente prima di stabilirti su One True Parser
  • Può aiutare a rompere un blocco di progettazione. Se non puoi decidere su un particolare modello di oggetto, ad esempio, puoi creare un po 'di codice e vedere come si adatta.

La risposta a questa domanda è come la risposta a molti in programmazione: dipende. Dipende dal progetto: hai bisogno di un audit trail di progettazione, il processo aiuta te ei tuoi colleghi sviluppatori a comprendere appieno le decisioni di cui hai bisogno, ti aiutano attivamente o ti trattengono da Getting Stuff Fatto? È fondamentale che il progetto sia assolutamente corretto o che alcuni difetti possano essere scoperti e risolti in un momento successivo? Come è il tuo periodo di tempo? Quale esperienza puoi portare al problema? Infine, capisci bene quale problema devi risolvere?

Al momento, ciò che funziona per me è fare un grande disegno su carta. Questo descriverà le parti principali dell'applicazione e come comunicheranno. Di solito disegno un diagramma di oggetti e alcuni diagrammi di flusso / codice psuedocode / reale per le sezioni più difficili. Poi salto dritto, una sezione alla volta. Se un difetto nel modello sta causando un problema, posso sempre tornare alle specifiche di progettazione e rivederle per quell'area. E cambiare un buon design iniziale di solito non significa che più di un po 'dovrà cambiare.

    
risposta data 02.08.2011 - 19:43
fonte
8

Mi è stato insegnato a programmare nello stesso modo in cui costruisci una ferrovia modello.

Quando costruisci un modello di ferrovia, metti un pezzo di pista e metti un motore in pista. Se si muove, metti il prossimo pezzo di binario, e vedi se il motore si muove su quella traccia. Continui finché non hai completato il ciclo e anche il motore ha completato il ciclo.

Il vantaggio di questo metodo di costruire un modello di ferrovia è che se il motore smette di muoversi, sei abbastanza sicuro di quale pezzo di pista sia il problema. Quello che hai appena posato.

La programmazione è simile. Devi fare l'analisi e il design, ma ad un certo punto, devi iniziare a tracciare la pista. La tua prima iterazione potrebbe essere nient'altro che moduli fittizi. Va bene, a patto che il progetto venga eseguito senza interruzioni.

Si aggiunge un metodo alla volta (idealmente) o la quantità minima di metodi per ottenere qualcosa da eseguire. Ogni volta, vedi se il motore si muove (il progetto viene eseguito senza interruzioni).

Potresti scoprire come stai stabilendo che hai bisogno di un raccordo aggiuntivo (alcuni metodi aggiuntivi). Va bene, finché non stai cambiando radicalmente il design. Se stai modificando radicalmente il design, interrompi la codifica. Dedica un po 'di tempo a pensare al design e apportare le modifiche al design prima di riprendere la codifica.

Una volta posizionati gli ultimi pezzi di traccia (terminati gli ultimi metodi), il progetto dovrebbe essere eseguito senza interruzioni. Perché hai provato tutti insieme. Proprio come i costruttori di ferrovie modello.

    
risposta data 02.08.2011 - 19:45
fonte
4

Il rapporto tra pensiero e azione dipende da un numero di variabili, che vanno dalla complessità del problema al dominio fino agli obiettivi finali. Non esiste un unico approccio a taglia unica per capire quanto pensiero e pianificazione hai bisogno in anticipo rispetto a quando puoi "hackerare" in un programma.

Se hai un problema complesso o stai lavorando su qualcosa che è cruciale per la vita o la missione, è necessario dedicare del tempo a capirlo e pensare a soluzioni e trade-off in anticipo. Se vuoi imparare rapidamente una tecnologia, una libreria o un framework, magari saltare direttamente dentro e fare in modo che i tuoi errori in un ambiente prototipo usa e getta funzionino al meglio. Altre opzioni includono la prototipazione evolutiva - abbastanza pensiero e design per essere sicuri di poter evolvere il tuo lavoro in un prodotto finito, ma non così tanto da essere costretto a percorrere una singola strada.

    
risposta data 02.08.2011 - 18:51
fonte
2

Come notato da @Thomas, non esiste una soluzione valida per tutti. In questa era di potenza e memoria di calcolo abbondanti, la maggior parte dei problemi con cui ci troviamo ad affrontare non sono difficili, quindi quasi ogni approccio andrà a buon fine. Tuttavia, ci sono ancora aree in cui puoi fallire miseramente se cerchi di capire una soluzione al volo, scrivendo subito il codice.

Ad esempio, un'app a cui ho lavorato analizzava le reti mobili. Se hai bisogno di scrivere codice per analizzare una rete di un paio di migliaia di nodi su una dozzina di diversi livelli di rete, che dovrebbe funzionare non su supercomputer ma su semplici laptop dual-core, è meglio trovare i migliori algoritmi grafici conosciuti dall'umanità prima iniziando a scrivere qualsiasi codice. L'alternativa potrebbe essere quella di realizzare dopo un anno e mezzo di entusiasmante sviluppo che il tuo algoritmo, sebbene fornisca risultati corretti per la tua rete di test di 10 nodi, sia O (n 4 ) termina quindi dopo due anni portatile, quando alimentato con il piano di rete della vita reale su cui sta lavorando in questo momento ...

    
risposta data 02.08.2011 - 19:09
fonte
2

Why don't more people just hack away and put a program together without having a preconceived idea of what it's going to look like?

Molti persone fanno proprio questo, durante la loro carriera. Questo sito è pieno di domande. Gli altri siti affiliati sono pieni di domande da parte di altre persone che cercano di utilizzare il software che hanno scritto.

Il tipo di persone che rilascia il codice, come si dice, spesso dice qualcosa come "Il codice è la sua documentazione". Il codice è non documentazione. Il codice non è una dimostrazione del tuo intento, è una versione di quello che ricordi come l'intento, oltre a un sacco di cose che ti interessavano lungo il percorso, alcune delle quali si rivelarono non utili ma non avevi tempo per rimuovere. Oh, e quella fantastica idea che avevi dopo due notti di sonno, ma molta caffeina, che avrebbe rivoluzionato l'intero progetto, so solo che non sai nemmeno come si compila, per non parlare di cosa avrebbe dovuto fare - o precisamente quale effetto avrà se lo rimuovi.

Senza un qualche tipo di documento di progettazione, per quanto minimo, in che modo i tuoi collaboratori (o successori) indicano quali bit estendere e quali eliminare? Quel documento non deve essere scritto all'inizio, ma per un progetto di qualsiasi dimensione e vale la pena deve accadere ad un certo punto.

Spew-and-refactor funziona per progetti solisti, fino a un certo punto (e le persone che sono buone giudiche su dove quel punto è valsa la pena conoscere). È meno pratico per le squadre; come funzionano le persone in modo efficiente in parallelo senza un minimo consenso sulle specifiche? La metodologia agile è in gran parte un tentativo di risolvere quel problema senza uccidere l'entusiasmo nativo della gente per la codifica.

    
risposta data 30.08.2013 - 09:23
fonte
1

Generalmente, la programmazione è un esercizio di astrazione. Pertanto, qualsiasi tentativo di attualizzare qualsiasi soluzione particolare ti porterà indubbiamente a giudicare erroneamente la portata del tuo sforzo.

Non sei così bravo a giudicare la complessità. Fidati di me, non lo sei.

Il miglior codice inizia con uno schema di ciò che vuoi realizzare e iterativamente cresciuto in blocchi. Con il codice successivo costruito su se stesso. Nelle fasi di pianificazione di un progetto è molto più utile sedersi ed elencare ciò che il programma NON sta per fare. In questo modo, almeno, non soccomberai a cercare di far bollire quel maledetto oceano.

link

    
risposta data 30.08.2013 - 07:55
fonte
0

So che è stata data una risposta, ma non sono convinto che Graham intendesse ignorare tutte le panoramiche di alto livello o progettare in anticipo. Penso al problema in anticipo, ho delle specifiche, ecc., Ma ho ancora completamente capito cosa sta dicendo mentre lavoro allo stesso modo.

Per me il "hacking away" non è quello che farai, ma come lo farai. A scuola mi è stato insegnato lo pseudo-codice e sto progettando il codice attuale. Per me, è sciocco. Prenderò una panoramica di alto livello, una bussola e vi sbarazzerò di lì. Non cercherò di pensare a tutto il codice perché non sono un compilatore o un computer e non riesco a comprendere le conseguenze di tutto il mio codice su carta. Lanciamo un'implementazione inefficiente o incompleta delle specifiche o del design e poi "la modelliamo" da lì.

    
risposta data 05.08.2011 - 18:54
fonte
0

Bene, chi sono io per contestare ciò che dice pg, ma ... penso che l'approccio migliore probabilmente varia da individuo, e che - nella misura in cui potrebbe esserci una verità oggettiva a questo punto - la verità risiede probabilmente in il mezzo da qualche parte. Per lo meno, penso che fare una dicotomia tra "nessuna pianificazione in anticipo" e "capire tutto in anticipo" sia una falsa dicotomia. È un continuum, nella mia esperienza.

Personalmente mi avvicino di più allo stile di programmazione esplorativa e al "capirlo mentre vado", ma allo stesso tempo, due dei miei strumenti di programmazione preferiti sono uno sketchpad degli artisti e un set di matite colorate. C'è sicuramente un momento e un luogo in cui sedersi e tracciare relazioni di alto livello e visualizzare le cose per capire come le cose andranno bene insieme. Bene, c'è per me.

Ancora una volta, penso che questo dipenda molto dall'individuo ... e anche dal dominio del problema e dalla complessità intrinseca del programma. Cioè, un semplice programma di calcolatrice da riga di comando (si pensi "povero uomo bc") probabilmente richiederebbe una pianificazione meno anticipata rispetto a un sistema ERP per un'azienda di 30.000 dipendenti.

    
risposta data 10.08.2011 - 22:51
fonte
0

Penso che il flusso di lavoro sia molto individuale per ogni programmatore. Utilizza il metodo che funziona meglio per te.

Io, di solito, di solito inizio con una carta bianca e una matita (o una lavagna molto grande se ne ho una). Sto prima disegnando diagrammi e relazioni di classe. Quindi lo affino finché non avrò una struttura di base. Faccio anche le macchine statali in questa fase. A questo punto nessun codice è stato scritto o pensato, solo classi e relazioni.

Ora questo è solo uno schizzo perduto e mentre inizio a programmare le mie lezioni mi imbatterò in altre domande sul design. Poi torno alla lavagna (o alla carta) e analizzo i nuovi problemi, a volte intendo a strappare parte del design originale.

Questo è anche simile a come funziona Design agile (nota SIMILE a tutti voi che vi lamenterete). Esiste tutta una scienza su come monitorare lo stato di avanzamento del progetto utilizzando questo metodo, poiché il numero di nuovi compiti accelererà all'inizio e dovrebbe svanire fino alla fine del progetto.

L'idea è di iterare codice e design. Abbiamo usato questo processo nella mia ex società (con 130 sviluppatori) e funziona benissimo. Abbiamo anche usato Doxygen per produrre diagrammi di classi e relazioni dal codice. Questo è stato un modo rapido per avere una buona panoramica del design effettivamente codificato, per individuare difetti e relazioni mancanti.

Se questo funziona per te o no, non posso dirlo. Devi provare e vedere cosa funziona meglio per te.

    
risposta data 26.12.2011 - 03:22
fonte
0

Interpreterò anche i miei due centesimi.

Scrivere un programma completo su carta prima di iniziare è un esercizio "CS 101" che funziona per Hello World. Ma sputare il codice senza prendersi del tempo per pensare a ciò che si vuole ottenere è anche una perdita di tempo.

Tra questi due estremi, hai la gamma completa di metodologie software, da hard Waterfall (serie espansiva di specifiche, praticamente una uscita alla fine) ad agile (specifiche "leggere" con tempi di risposta molto veloci tra rilasci e costanti " dialogo "cliente".

In ogni caso, devi sapere cosa stai costruendo prima di poter iniziare, qualunque sia la metodologia. Ciò contribuirà a inquadrare l'architettura del programma. Waterfall metterà l'accento sull'avere architettato l'intero sistema prima di iniziare la codifica, in modo che tu sappia con cosa finirai. Agile metterà l'accento su "specifica la funzionalità minima da raggiungere per la prossima iterazione" e ti ammonirà di essere preparato alla re-arcitecture costantemente (creando apposite suite di test e simili in modo tale da poter effettivamente svolgere tale lavoro ).

Nota che nessuna metodologia ti dirà di iniziare a programmare senza pensare, e in effetti dovresti avere una buona idea di ciò che stai cercando di fare (che si tratti di Waterfall o di un'area più piccola con Agile). ). Improvvisi un po 'in "COME" fai qualcosa, non in "COSA" stai cercando di fare.

Posso tracciare un parallelo con ciò che impari quando prendi lezioni di recitazione. Una grande parte è "improvvisare". Quando si inizia un'improvvisazione, è necessario entrare con il minor numero possibile di pietre e essere pronti ad abbandonare la propria idea se qualcuno prende la scena in un'altra direzione. Hai bisogno di grandi capacità di ascolto e devi accettare le proposte degli altri. L'importante è venire sul palco con un personaggio, una situazione, forse una sensazione che vuoi trasmettere, e potenzialmente un finale verso il quale vuoi prendere la scena. Ma più lontano è l'idea nella scena, più è probabile che finirai da qualche altra parte. Alla fine, è un modo di pensare molto "agile", che potrebbe essere quello con cui stai lottando qui.

Ora, se stai parlando al livello "Let's write code" (specifiche, storie o qualsiasi altra cosa sia disponibile), allora tocca a te. Alcune persone scrivono pseudocodici, alcuni scrivono commenti prima del codice reale (in un "riempimento in bianco") e alcuni iniziano scrivendo dei test (vedi Test Driven Development). In ogni caso, l'obiettivo è di incorniciare la tua idea in modo da raggiungere ciò che hai deciso di fare nel tuo particolare metodo. A quel livello, la maggior parte delle persone pensa prima di scrivere il codice vero e proprio. Ma arrivare al punto di scrivere il codice prima della mano su carta mi sembra eccessivo ...

    
risposta data 26.12.2011 - 17:23
fonte
0

Citazione obbligatoria di Hunter S. Thomson ma funziona sempre per me

Se hai una chiara idea di cosa vuoi ottenere, sai come strutturare il tuo codice e sei un buon programmatore, spesso è più veloce solo per scrivere il codice.

    
risposta data 30.08.2013 - 08:52
fonte

Leggi altre domande sui tag