Ho provato a pianificare le cose in anticipo, ma non riesco proprio a prevedere tutto fino a quando non inizierò a elaborare un po 'di codice.
È allettante pensare che una pianificazione perfetta ti dia una progettazione / architettura del software perfetta, tuttavia, risulta categoricamente falso. Ci sono due grossi problemi con questo. In primo luogo, "sulla carta" e "il codice" raramente corrispondono, e il motivo è perché è facile dire come dovrebbe essere fatto invece di farlo effettivamente . In secondo luogo, cambiamenti imprevisti nei requisiti diventano evidenti alla fine del processo di sviluppo che non avrebbero potuto essere motivati sin dall'inizio.
Hai sentito parlare del movimento Agile? È un modo di pensare in cui valutiamo "reagire al cambiamento" anziché "seguire un piano" (tra le altre cose). Ecco il manifesto (è una lettura veloce). Puoi anche leggere su Big Design Up Front (BDUF) e quali sono le insidie.
Sfortunatamente, la versione aziendale di "Agile" è un gruppo di falsi (maestri di scrum certificati, processi pesanti nel nome di "Agile", forzare la mischia, forzare una copertura del codice del 100%, ecc.) E di solito si traduce in cambiamenti del processo asinino perché i gestori pensa che Agile sia un processo e un proiettile d'argento (di cui non è nessuno dei due). Leggi il manifesto agile, ascolta le persone che hanno iniziato questo movimento come lo zio Bob e Martin Fowler e non farti risucchiare dalla versione senza senso di "corporativo Agile".
In particolare, di solito puoi cavartela semplicemente facendo TDD (Test Driven Development) su codice scientifico , e ci sono buone probabilità che il tuo progetto software finisca maledettamente bene. Questo perché il codice scientifico di successo ha per lo più interfacce ultra-utilizzabili, con le prestazioni come una preoccupazione secondaria (e talvolta in competizione), e quindi puoi cavartela con un design più "avido". TDD obbliga il tuo software a essere ultra-utilizzabile , perché scrivi come vuoi che le cose vengano chiamate (idealmente) prima di implementarle. Forza anche piccole funzioni con piccole interfacce che possono essere rapidamente chiamate in modo semplice, "input" / "output", e ti mette in una buona posizione per refactoring nel caso in cui i requisiti cambino.
Penso che possiamo essere tutti d'accordo sul fatto che numpy
sia un software di calcolo scientifico di successo. Le loro interfacce sono piccole, super utilizzabili e tutto gioca bene insieme. Si noti che numpy
la guida di riferimento raccomanda esplicitamente TDD: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . Ho usato TDD in passato per il software di imaging SAR (Synthetic Aperature Radar): e posso anche affermare che funziona molto bene per quel particolare dominio.
Avvertenza: la parte di progettazione di TDD funziona meno bene nei sistemi in cui un refactoring fondamentale (come decidere che è necessario che il software sia altamente concorrenziale) sarebbe difficile, come in un sistema distribuito. Ad esempio, se dovessi progettare qualcosa come Facebook in cui hai milioni di utenti simultanei, fare TDD (per guidare il tuo design) sarebbe un errore (comunque va bene usarlo dopo averne uno preliminare , e fare semplicemente "test del primo sviluppo "). È importante pensare alle risorse e alla struttura dell'applicazione prima di passare al codice. TDD non ti condurrà mai a un sistema distribuito a disponibilità elevata.
Come posso evitare di sentirmi sempre come se avessi ricostruito completamente il mio programma da zero, lo farei molto meglio?
Alla luce di quanto sopra, dovrebbe essere in qualche modo evidente che un design perfetto è in realtà impossibile da raggiungere, quindi inseguire un design perfetto è un gioco folle. Puoi davvero solo avvicinarti. Anche se pensi di poter riprogettare da zero, probabilmente ci sono ancora requisiti nascosti che non si sono mostrati. Inoltre, le riscritture impiegano almeno il tempo necessario per sviluppare il codice originale. Quasi certamente non sarà più breve, dal momento che è probabile che il nuovo design abbia problemi propri, oltre a dover implementare nuovamente tutte le funzionalità del vecchio sistema.
Un'altra cosa da considerare è che il tuo design conta davvero solo quando cambiano i requisiti .Non importa quanto sia brutto il design se nulla cambia (supponendo che sia completamente funzionale per gli attuali casi d'uso). Ho lavorato su una linea di base con un'istruzione switch di 22.000 righe (la funzione era ancora più lunga). È stato un design terribile? Cavolo sì, è stato terribile. L'abbiamo risolto? No. Funzionava perfettamente così com'era, e quella parte del sistema non ha mai causato crash o bug. È stato toccato solo una volta nei due anni in cui ero al progetto e qualcuno, hai indovinato, ha inserito un altro caso nello switch. Ma non vale la pena prendersi il tempo di riparare qualcosa che viene toccato così raramente, semplicemente non lo è. Lascia che il design imperfetto sia così com'è, e se non si rompe (o si rompe costantemente), non correggerlo. Così forse si potrebbe fare di meglio ... ma varrebbe la pena riscrivere? Cosa guadagnerai?
HTH.