È possibile scrivere software che non ha bisogno di essere continuamente modificato?

23

Ho scritto un sacco di software in molte lingue diverse e ho anche "scritto" l'hardware per l'uso con FPGA usando Verilog e VHDL.

Tendo a divertirmi a scrivere hardware più del software, e penso che uno dei motivi principali è che è possibile scrivere hardware che è "fatto" e non deve mai essere modificato: si definiscono le interfacce e la funzionalità, si scrive un banco di prova, implementare il modulo hardware, quindi testarne il funzionamento con un simulatore. Quindi puoi fare affidamento su quel modulo hardware come elemento di base per creare qualcosa di più grande e migliore: se hai bisogno di aggiungere una funzione a quel modulo, crei un secondo modulo e aggiungi lì la funzionalità. Non butti mai via il modulo originale poiché funziona perfettamente e può essere comunque utile.

Una delle mie principali frustrazioni con il software è che non viene mai "fatto". C'è sempre un'altra funzionalità da aggiungere. Spesso quando si aggiunge una funzione si introduce un bug da qualche altra parte che stava funzionando bene prima. Questo non succede nell'hardware finché le interfacce non sono violate.

Per essere chiari, non sto promuovendo la creazione di una versione di qualcosa con un elenco di funzionalità e questo è per sempre: sono a favore di iterazioni e rilasci multipli nel tempo per aggiungere nuove funzionalità. Semplicemente non voglio attirare il codice a sinistra e trovare un bug sulla destra, e questo sembra accadere dopo aver aggiunto una nuova funzionalità.

È possibile scrivere software in modo simile in cui l'hardware è "scritto"? Esiste una buona metodologia di sviluppo del software che consenta di realizzare sempre progressi futuri e di aggiungere nuove funzionalità senza dover riscrivere il codice esistente e introdurre nuovi bug?

    
posta Nathan Farrington 20.01.2012 - 09:27
fonte

11 risposte

16

Maybe it has something to do with well-defined interfaces and testing, like hardware?

Esattamente i miei pensieri!

I moduli ben progettati con interfacce chiare tendono ad essere essenzialmente perfetti. Pensa a qualcosa come String classe di Java. È un programma per computer, ma ha un'interfaccia cristallina. Non ci sono bug noti in esso. Fa quello che dovrebbe fare, perfettamente. Certo, è stato ampiamente testato negli ultimi 15 anni, e dal momento che praticamente tutti i programmi usano String s come elementi costitutivi di base, qualsiasi bug in esso sarebbe presto notato. Qualsiasi "stranezza" - non strettamente bug, ma i dettagli di design che meritano di essere considerati - come quelli descritti qui link sono ben noto ormai, e quindi può essere preso in considerazione.

Il software Buggy è in parte un problema culturale: le persone sono abituate a software buggy e, a differenza dell'hardware, il software può essere facilmente riparato in seguito, quindi non deve essere perfetto inizialmente (o mai, perché hey, dobbiamo spedire ora , sistemiamolo nella prossima versione). Ma per una gran parte, è un vero problema di complessità: la complessità del software è aumentata costantemente negli ultimi 50 anni circa, ma il cervello umano è lo stesso. Quando la crescente difficoltà nel raggiungere la perfezione e la crescente facilità di sistemare le cose in seguito (build veloci, automatici, distribuzione internet) si combinano con la pressione del programma e la mancanza di disciplina, il risultato è quello che è.

Is there a good software development methodology that allows forward progress to always be made and allows new functionality to be added without needing to rewrite existing code and introduce new bugs?

Probabilmente nessun proiettile d'argento, ma una buona combinazione di buone pratiche, incluso ma non limitato a:

  • Moduli semplici e autonomi. In altre parole, basso accoppiamento e alta coesione.
  • immutabilità. Particolarmente importante con la crescita della concorrenza.

Vale la pena notare che entrambi i punti mirano a ridurre la complessità. Questo è il punto chiave. L'entropia tende sempre ad aumentare e, a meno che non lo combattiamo, presto affogheremo nella complessità. È anche interessante notare che negli ultimi anni i linguaggi di programmazione si sono evoluti verso l'incoraggiamento o addirittura l'applicazione delle pratiche sopra citate. In particolare, l'aumento dei linguaggi funzionali è proprio questo: le funzioni pure restituiscono sempre lo stesso valore per lo stesso input, non esiste uno stato in esse. Quindi esegui solo componi funzioni puri che prendono e restituiscono valori immutabili e limitano l'inevitabile mutabilità a piccoli luoghi ben definiti invece di diffonderlo ovunque. Controlla questo: link

    
risposta data 20.01.2012 - 10:06
fonte
9

La differenza è quanto più semplice ed economico è modificare il software rispetto all'hardware. Se l'hardware fosse facile ed economico da modificare e spedire ai clienti, lo farebbero.

I think if I could sum up my poorly-expressed question it would be something like, "how can I have more fun writing software by not introducing bugs into working code and always making forward progress?" Maybe it has something to do with well-defined interfaces and testing, like hardware?

Devi assolutamente controllare sviluppo basato sui test .

    
risposta data 20.01.2012 - 09:59
fonte
6

Commenterò alcune delle tue osservazioni, sperando di ottenere la risposta da questi commenti.

One of my main frustrations with software is that it is never "done".

Questo perché le specifiche della soluzione sono incomplete o perché il piano per fornire miglioramenti non è accurato. Questo può accadere a qualsiasi software di progetto, hardware o altro.

Is there a good software development methodology that allows forward progress to always be made and allows new functionality to be added without needing to rewrite existing code and introduce new bugs?

Naturalmente, la creazione di moduli indipendenti dovrebbe ridurre notevolmente la dipendenza. Questo deve essere considerato quando si progetta il software. È necessario considerare la separazione di preoccupazioni, livelli, livelli, oggetti controller, interfacce, ecc.

"how can I have more fun writing software by not introducing bugs into working code and always making forward progress?"

1-Comprendere attentamente i requisiti. Potrebbe essere necessario prendere in considerazione la possibilità di chiudere i requisiti prima del design. Se fai uno sviluppo iterativo, non c'è possibilità di farlo. Alcune metodologie incoraggiano questo, ma personalmente, penso che questo non sia positivo per tutti i tipi di progetto. Costruire software su solidi requisiti consente una progettazione migliore.

2: fai capire al tuo utente questa filosofia a lungo termine.

3-Plan implementation carefully

4-Design prima del codice.

5-Usa design generico quando appropriato.

6-Utilizzare i prototipi come strumento di conferma del progetto.

    
risposta data 20.01.2012 - 10:21
fonte
4

Come le persone sono in genere molto veloci a sottolineare, uno dei vantaggi del software è che dovrebbe essere facile e relativamente economico da cambiare rispetto all'hardware. Questo è particolarmente importante quando ti rendi conto tardi che hai qualcosa di fondamentalmente sbagliato. Fai lo stesso con l'hardware e perdi un milione di dollari, così come hai detto, usi i tuoi simulatori ecc. E ne provi il bazinga. Questo penso sia dove il paradigma fallisce un po 'quando si passa al software.

Entra nella testa dello sviluppatore del software medio e quello che hai è una persona molto impegnata con una scadenza incredibilmente stretta. Il suo manager sta dicendo che è giusto lasciare qualche bug perché è sempre possibile correggerlo in un secondo momento. I test sono spesso un ripensamento, ma anche in uno scenario basato su test, i test vengono mantenuti minimi e il codice scritto al minimo dei test, e spesso vengono prese scorciatoie in modo che molti dei casi limite possano essere ignorati. Il sistema può essere accuratamente testato unitamente, ma viene raramente testato rigorosamente nel suo complesso, e altrettanto raramente sottoposto a stress in qualsiasi grado. Aggiungete a questo che scrivete il software da zero e vi sono poche opportunità di simulare il software prima di impegnarvi a scriverlo, principalmente perché raramente scriviamo software dallo stesso tipo di blocchi predefiniti che troverete nell'hardware. Preso da questa prospettiva - che non credo sia un esempio troppo esagerato - il software non è testato allo stesso livello dell'hardware, perché realisticamente non può essere, e tentare di farlo non sarebbe Seent per essere molto redditizio.

Torna alla domanda dell'OP. Potresti definire un sistema di blocchi da cui derivare tutto il tuo software? Possibilmente. Sarebbe molto redditizio? Probabilmente no, perché quando avrai a disposizione un sistema abbastanza robusto di componenti, test e altri strumenti per supportare questo sistema di programmazione ideale , scoprirai che la tua concorrenza ti avrebbe già battuto sul mercato, e ancora peggio, dal punto di vista del programmatore medio, probabilmente si troverà uno stile di programmazione "cookie-cutter" molto limitante e molto probabilmente noioso. Lavoro personalmente su un'API, in cui la maggior parte del codice del modulo è stata perfezionata e standardizzata in modo così completo, che tutto ciò che faccio ora è generare un modello di codice e riempire gli spazi vuoti. La maggior parte del mio tempo può essere speso scrivendo codice connettore semplice e portando i moduli fuori dalla porta il più velocemente possibile. È davvero sconvolgente. Ci sono pochissime opportunità di fare qualcosa di più che semplicemente codificare lo stesso tipo di cose più e più volte, così quando arriva un'altra opportunità di progetto, colgo l'occasione per poter fare QUALCHE altro.

Quindi come si può arrivare a fornire software di alta qualità e ben gestito, e tuttavia divertitevi a farlo? Credo che questo dipenda dalla scelta degli strumenti e della metodologia. Per me la risposta è stata quella di utilizzare l'uso di una buona API BDD, perché mi ha permesso di creare codice molto facile da leggere, ma altamente granulare. Posso creare una serie di test con un numero minimo di metodi riutilizzabili e descrivere i miei test nella lingua delle specifiche. In questo modo, mi avvicino a un approccio di sviluppo più compositivo, fatta eccezione per il fatto che sono responsabile della progettazione e del controllo degli elementi costitutivi. Inoltre, l'output di test individua la parte esatta del test in cui si verifica l'errore, in modo che non debba indovinare se i guasti sono nell'impostazione o nell'asserzione. Ciò significa che dedico più tempo a concentrarmi sulla risoluzione dei problemi invece di inseguirli, il mio tempo è usato in modo più efficiente, ho più lavoro svolto più rapidamente e posso passare ad altri compiti interessanti più rapidamente.

Anche l'ottimizzazione della metodologia aiuta. Sono un grande sostenitore per l'applicazione di principi di sviluppo snelli e la combinazione con molte delle altre tecniche e principi su cui il movimento Agile ha battuto da molti anni. Avendo eliminato la maggior parte delle pratiche dispendiose che trovavo così frustranti ha aiutato moltissimo a rendere lo sviluppo un'attività più piacevole. Mi rimane ancora il problema che a volte - ma si spera non troppo spesso - i bug appariranno nel mio codice, tuttavia ora mi trovo con più tempo e ancora più incentivo a dedicare più tempo a scrivere test più robusti ea puntare a 100 % di copertura del test. Ancora meglio, è davvero bello vedere tutte quelle luci verdi apparire alla fine della mia giornata, ed essere in grado di fornire un rapporto di prova completo generato automaticamente da consegnare al mio capo alla fine della giornata.

    
risposta data 20.01.2012 - 11:40
fonte
3

One of my main frustrations with software is that it is never "done". There is always another feature to add.

Se ciò ti frustra, considera una carriera diversa. Scherzi a parte.

Il punto del software deve essere in grado di aggiungere funzionalità. L'intero motivo per cui abbiamo inventato "software" è stato in primo luogo in modo da poter aggiungere funzionalità.

Often when adding a feature it introduces a bug somewhere else that was working just fine before.

Questo è un problema di controllo qualità.

This doesn't happen in hardware as long as the interfaces are not violated.

Questo vale anche per il software.

Is there a good software development methodology that allows forward progress to always be made and allows new functionality to be added without needing to rewrite existing code and introduce new bugs?

Sì. Devi effettivamente esercitare la garanzia della qualità.

    
risposta data 20.01.2012 - 11:52
fonte
2

Is it possible to write software in a similar way in which hardware is "written"? Is there a good software development methodology that allows forward progress to always be made and allows new functionality to be added without needing to rewrite existing code and introduce new bugs?

Ti consiglio di esaminare i " metodi formali " per verificare la correttezza dei progetti e del software. Gli strumenti del simulatore che utilizzi per la progettazione hardware stanno cercando di fare qualcosa di simile. Non credo che gli strumenti per i metodi formali siano ovunque vicino ad essere utili nell'industria in questo momento, e le uniche industrie che hanno forti incentivi a non avere difetti sono avionica e medicine (abbastanza interessante, la FDA dice chiaramente "il software è diverso dall'hardware" su quel collegamento). Inoltre, se stai sviluppando con Verilog / VHDL, allora stai seguendo la logica binaria. Questo riduce drasticamente la complessità. Non ci sarà un equivalente hardware per un problema Y2K.

Il grosso problema è che le cose sono complesse. E non puoi eliminare la complessità, puoi solo spostarla.

    
risposta data 21.01.2012 - 01:31
fonte
1

it is possible to write hardware that is "done" and never needs to be modified: you define the interfaces and the functionality, write a test bench, implement the hardware module, then test the heck out of it using a simulator. Then you can rely on that hardware module as a building block to create something bigger and better: if you need to add a feature to that module, you create a second module and add the functionality there. You never throw away the original module since it is working just fine and can still be useful.

Nel mondo del software, chiamiamo quel "modulo" una libreria e lo usiamo allo stesso modo. Molte librerie sono costruite al punto che funzionano bene, e quindi si accontentano di fare il proprio lavoro senza modifiche finché qualcosa di importante non porta alla revisione successiva. Pensa a loro come un software che è stato conservato in resina epossidica: -)

One of my main frustrations with software is that it is never "done". There is always another feature to add. Often when adding a feature it introduces a bug somewhere else that was working just fine before. This doesn't happen in hardware as long as the interfaces are not violated.

Hogwash. Forse tu sei personalmente migliore di molti altri "hardware" di ferro non saldante, ma ho visto un numero qualsiasi di progetti di circuiti difettosi, chip in errore ( eg , il famoso problema Intel "f00f" ), ma ciò non riguarda il campo nel suo insieme. E dato che l'hardware "finto-duro" diventa "più morbido", i problemi diventano più difficili da prevenire.

Is it possible to write software in a similar way in which hardware is "written"? Is there a good software development methodology that allows forward progress to always be made and allows new functionality to be added without needing to rewrite existing code and introduce new bugs?

Sì. Non usiamo molto quelle metodologie. Tendono ad essere estremamente costosi da gestire e la maggior parte dei programmatori non ama lavorare con le loro restrizioni. Ma quando la vita umana è coinvolta, per esempio, beh, sì, proviamo a non uccidere gli utenti.

Un ultimo punto: il software ha un modello finanziario diverso dall'hardware, persino dall'hardware programmato. La maggior parte dei software non consumer e anche alcuni software consumer sono venduti in modo tale da incoraggiare il cambiamento. Quando puoi dire a un'azienda "Pagaci $ 10.000 ora più il 18% all'anno", puoi sostanzialmente rivendere il prodotto ogni pochi anni. Ma per giustificare questa tariffa, devi dare al cliente i cambiamenti che vogliono. Hmm ... pensando alla curva dell'obsolescenza dell'hardware di Apple, forse questa non è una differenza dopo tutto - l'hardware ti rende veramente re-buy!

    
risposta data 21.01.2012 - 01:03
fonte
0

how can I have more fun writing software by not introducing bugs into working code and always making forward progress?

Mi piacerebbe trovare una risposta definitiva alla tua domanda. Ma la realtà è che non esiste un modo semplice per farlo, ecco perché la programmazione estrema e le tecniche TDD stanno diventando così popolari. Devi abbracciare il cambiamento, perché sta per accadere. Non so se è più divertente in questo modo, ma molto meno stressante di sicuro; -)

link

Quando interagisci con l'hardware, l'hardware ha bisogno del valore x e questo è tutto (in teoria), ma quando interagisci con le persone oggi hanno bisogno di x, e domani possono aver bisogno di y, ecc. È così, bussines e le esigenze delle persone cambiano. Perché Persone! = Macchine, quindi il codice che MAI cambia la maggior parte delle volte non è possibile.

Come ho già detto nella mia risposta precedente / cancellata, cerca di evitare cambiamenti che non sono importanti facendo riflettere la gente prima di iniziare a programmare. Coinvolgere maggiormente gli utenti nel processo decisionale, ecc. Chiarire i costi delle modifiche, pianificare di più, ecc. Quelli non sono "modi di codifica", sono modi di "non codificare" perché con più se si tratta di requisiti ci saranno meno cambiamenti e più divertimento.

    
risposta data 20.01.2012 - 11:26
fonte
0

Is it possible to write software in a similar way?

Sì, lo è. Stai attento a come stai sviluppando hardware, prova tutto ciò che puoi e il tuo software sarà di qualità simile.

a proposito, non hai sentito parlare di bug HW? Molto più cattivo di qualsiasi bug SW e più difficile da risolvere (non solo l'aggiornamento del software)

    
risposta data 20.01.2012 - 12:53
fonte
0

Vorrei anche sottolineare che i bug del software nell'hardware possono spesso uccidere le persone. Quindi ci sono più cure per determinare accuratamente i requisiti e testarli in modo approfondito. E quei requisiti non devono cambiare fino a quando l'hardware non lo fa. E poiché il nuovo hardware potrebbe richiedere una riscrittura, sospetto che il cruft non si accumuli così tanto.

I requisiti aziendali, d'altro canto, cambiano costantemente, a volte difficilmente si può ottenere un requisito in produzione prima che venga richiesto un cambiamento. A volte, ho avuto la necessità di cambiare più volte prima che arrivi alla produzione. Questo è il risultato di diverse cose. In primo luogo, lo stakeholder del progetto sul lato business è spesso meno interessato a spendere il tempo per definire a fondo ciò che vuole perché è "occupato" e "importante" e la gente non morirà e le famiglie lo incoraggeranno o lo faranno gettare in prigione se fa saltare la sua parte del processo. In secondo luogo, gli stakeholder del progetto tendono ad avere un'idea migliore di ciò che vogliono fare l'hardware in quanto è meno astratto per loro. Davvero non sanno quello che vogliono finché non lo vedono. Quale è meno di aproblem con Hardware.

    
risposta data 20.01.2012 - 23:34
fonte
-1

Ci sono strumenti di alto livello con molti "mattoncini" finiti, come li chiami tu, che puoi combinare in applicazioni. I mattoni sono pezzi finiti che puoi usare, devi solo combinarli insieme. Forse pensi che sia più facile ... fino a quando il tuo cliente ti chiederà alcune modifiche strane e inaspettate.

    
risposta data 20.01.2012 - 15:04
fonte

Leggi altre domande sui tag