|
|
| << | < | > | >> |IndicePrefazione XIII Capitolo 1 Introduzione 1 1.1 Cos'è un computer 1 1.2 Cos'è la programmazione 2 1.3 Anatomia di un computer 3 1.4 Traduzione in codice macchina di programmi leggibili dagli utenti 8 1.5 Linguaggi di programmazione 10 1.6 Progettazione ed evoluzione dei linguaggi di programmazione 11 1.7 Acquisire familiarità con il computer 14 1.8 Compilare un programma semplice 17 Sintassi 1.1: un semplice programma 18 1.9 Errori 22 1.10 Il processo di compilazione 24 1.11 Algoritmi 27 Riepilogo 28 Letture 30 Esercizi di ripasso 30 Esercizi di programmazione 32 Capitolo 2 Tipi di dati fondamentali 35 2.1 Tipi di numeri 35 Sintassi 2.1: Istruzione di output 37 Sintassi 2.2: Definizione di variabile 38 Sintassi 2.3: Commenti 43 2.2 Input e output 44 Sintassi 2.4: Istruzione di richiesta di input 47 2.3 Assegnazione 48 Sintassi 2.5: Assegnazione 50 Sintassi 2.6: Cast 54 2.4 Costanti 56 Sintassi 2.7: Definizione di una costante57 2.5 Aritmetica 59 Sintassi 2.8: Chiamare una funzione 62 2.6 Stringhe 68 2.6.1 Variabili stringa 68 2.6.2 Stringhe secondarie 69 Sintassi 2.9: Chiamare una funzione membro 69 2.6.3 Concatenazione 70 2.6.4 Output formattato 72 Riepilogo 74 Letture 75 Esercizi di ripasso 75 Esercizi di programmazione 78 Capitolo 3 Oggetti 85 3.1 Costruire oggetti 86 Sintassi 3.1: Costruzione di un oggetto 87 Sintassi 3.2: Definizione di un oggetto 87 3.2 Utilizzare gli oggetti 88 3.3 Oggetti della vita reale 93 3.4 Visualizzare le forme grafiche 96 3.5 Strutture grafiche 97 3.6 Scegliere un sistema di coordinate 104 3.7 Richiedere l'input dalla finestra di grafica 108 3.8 Confrontare le informazioni visive e numeriche 109 Riepilogo 113 Letture 114 Esercizi di ripasso 115 Esercizi di programmazione 116 Capitolo 4 Controllo di base del flusso 121 4.1 L'istruzione if 121 Sintassi 4.1: Istruzione if 122 Sintassi 4.2: Istruzione di blocco 123 4.2 L'istruzione if/else 126 Sintassi 4.3: Istruzione if/else 126 4.3 Operatori relazionali 128 4.4 Verificare i dati in input 132 4.5 Cicli semplici 136 Sintassi 4.4: Istruzione while 137 4.6 Elaborare una sequenza di dati in input 140 4.7 Utilizzare le variabili booleane 143 Riepilogo 149 Letture 149 Esercizi di ripasso 150 Esercizi di programmazione 152 Capitolo 5 Funzioni 159 5.1 Funzioni viste come "scatole nere" 159 5.2 Scrivere funzioni 160 Sintassi 5.1: Definizione della funzione162 5.3 Commenti associati alle funzioni 165 5.4 Valori restituiti 168 Sintassi 5.2: Istruzione return 169 5.5 Parametri 171 Sintassi 5.3: Dichiarazione di funzione, o prototipo 174 5.6 Effetti collaterali 175 5.7 Procedure 176 5.8 Parametri passati per riferimento 177 Sintassi 5.4: Parametro passato per riferimento 178 5.9 Ambito delle variabili e variabili globali 180 Sintassi 5.5: Parametri passati per riferimento dichiarati come costanti 180 5.10 Miglioramento graduale 182 5.11 Dallo pseudocodice al codice 185 5.12 Analisi dettagliate 191 5.13 Requisiti indispensabili 196 Sintassi 5.6: assert 196 Riepilogo 201 Letture 202 Esercizi di ripasso 202 Esercizi di programmazione 206 Capitolo 6 Classi 213 6.1 Scoprire le classi 214 6.2 Interfacce 217 Sintassi 6.1: Definizione della classe 217 6.3 Incapsulamento 220 6.4 Funzioni membro 222 Sintassi 6.2: Definizione della funzione membro 223 6.5 Costruttori predefiniti 226 Sintassi 6.3: Definizione di un costruttore 227 6.6 Parametri nei costruttori 230 Sintassi 6.4: Costruttore con elenco di inizializzazione dei campi233 6.7 Accedere ai campi dati 234 6.8 Confrontare funzioni membro e funzioni non membro 236 6.9 Compilazione separata 238 Riepilogo 244 Letture 244 Esercizi di ripasso 244 Esercizi di programmazione 246 Capitolo 7 Controllo di flusso avanzato 251 7.1 Alternative multiple 251 7.2 Istruzioni nidificate 259 7.3 Operazioni booleane 263 7.4 La legge di De Morgan 267 7.5 Il ciclo for 269 Sintassi 7.1: Istruzione for 270 7.6 Il ciclo do 275 Sintassi 7.2: Istruzione do/while 276 7.7 Cicli nidificati 280 7.8 Elaborare testo in input 284 7.9 Simulazioni 288 Riepilogo 294 Letture 294 Esercizi di ripasso 294 Esercizi di programmazione 299 Capitolo 8 Test e debugging 305 8.1 Lo unit test 305 8.2 Selezionare i casi di test 310 8.3 Valutare i risultati dei test 311 8.4 Asserzioni 314 8.5 Tracciabilità dell'esecuzione del programma 315 8.6 Il debugger 316 8.6.1 Utilizzare il debugger 317 8.6.2 Una sessione di debugging di esempio 319 8.6.3 Spostarsi in un programma 321 8.6.4 Esaminare gli oggetti 323 8.7 Strategie 324 8.7.1 Riprodurre l'errore 324 8.7.2 Dividere e conquistare 325 8.7.3 Conoscere le operazioni che dovrebbe svolgere il programma 325 8.7.4 Osservare tutti i dettagli 326 8.7.5 Comprendere ciascun errore prima di correggerlo 326 8.8 Limiti del debugger 326 8.8.1 Funzioni ricorsive 326 8.8.2 Registro delle variabili 327 8.8.3 Errori che spariscono utilizzando il debugger 327 Riepilogo 329 Letture 330 Esercizi di ripasso 330 Esercizi di programmazione 331 Capitolo 9 Vettori e array 333 9.1 Utilizzare vettori per memorizzare collezioni di dati 333 Sintassi 9.1: Definizione della variabile vettoriale 334 9.2 Indici vettoriali 336 Sintassi 9.2: Indice del vettore 336 9.3 Parametri di tipo vettore e vettori come valori restituiti 343 9.3.1 Rimuovere e inserire elementi 346 9.4 Vettori paralleli 350 9.5 Array 354 9.5.1 Definire e utilizzare gli array 354 Sintassi 9.3: Definizione della variabile di array 354 9.5.2 Array passati come parametri 356 9.5.3 Array di caratteri 358 9.5.4 Array bidimensionali 361 Sintassi 9.4: Definizione di array bidimensionali 362 Riepilogo 369 Letture 369 Esercizi di ripasso 369 Esercizi di programmazione 371 Capitolo 10 Puntatori 379 10.1 Puntatori e allocazione della memoria 379 Sintassi 10.1: Espressione new 380 Sintassi 10.2: Definizione di una variabile puntatore 380 Sintassi 10.3: Deriferimento di un puntatore 382 10.2 Rilasciare la memoria dinamica 384 Sintassi 10.4: Espressione delete 385 10.3 Utilizzi tipici dei puntatori 388 10.4 Array e puntatori 393 10.5 Puntatori a stringhe di caratteri 399 Riepilogo 403 Esercizi di ripasso 403 Esercizi di programmazione 406 Capitolo 11 Ereditarietà 409 11.1 Classi derivate 409 Sintassi 11.1: Definizione della classe derivata 410 11.2 Chiamare il costruttore della classe base 415 Sintassi 11.2: Il costruttore con l'inizializzatore della classe base 416 11.3 Chiamare le funzioni membro della classe base 417 11.4 Polimorfismo 423 Sintassi 11.3: Definizione di una funzione virtuale 426 Riepilogo 433 Esercizi di ripasso 433 Esercizi di programmazione 437 Capitolo 12 Stream 441 12.1 Leggere e scrivere file di testo 441 12.2 La gerarchia di ereditarietà delle classi di tipo stream 445 12.3 Stream di tipo stringa 448 12.4 Argomenti della riga di comando 451 12.5 Accesso casuale 457 Riepilogo 464 Letture 464 Esercizi di ripasso 465 Esercizi di programmazione 466 Capitolo 13 Design orientato agli oggetti 473 13.1 Il ciclo di vita del software 473 13.2 Schede CRC 478 13.3 Coesione 480 13.4 Coupling 482 13.5 Relazioni tra le classi 484 13.6 Implementare le associazioni 488 13.7 Esempio: visualizzare una fattura 489 13.7.1 Requisiti 490 13.7.2 Schede CRC 490 13.7.3 Diagrammi UML 493 13.7.4 Commenti sulle classi e sulle funzioni 493 13.7.5 Implementazione 495 13.8 Esempio: un gioco educativo 501 13.8.1 Requisiti 501 13.8.2 Schede CRC 502 13.8.3 Diagrammi UML 505 13.8.4 Definizione dei commenti di classi e funzioni 506 13.8.5 Implementazione 507 Riepilogo 518 Letture 519 Esercizi di ripasso 519 Esercizi di programmazione 520 Capitolo 14 Ricorsività 523 14.1 I numeri dei triangoli 523 14.2 Permutazioni 527 14.3 Pensare in modo ricorsivo 533 14.4 Funzioni ricorsive ausiliarie 537 14.5 Ricorsività reciproca 538 14.6 Efficienza della ricorsività 542 Riepilogo 549 Esercizi di ripasso 550 Esercizi di programmazione 550 Capitolo 15 Ordinamento e ricerca 555 15.1 Ordinamento per selezione 555 15.2 Analisi dell'algoritmo dell'ordinamento per selezione 558 15.3 Analisi delle prestazioni dell'algoritmo di ordinamento per selezione 559 15.4 Ordinamento per unione 561 15.5 Analisi dell'algoritmo di ordinamento per unione 565 15.6 Algoritmi di ricerca 569 15.7 Ricerca binaria 571 15.8 Cercare e ordinare dati reali 574 Riepilogo 577 Letture 577 Esercizi di ripasso 577 Esercizi di programmazione 580 Capitolo 16 Introduzione alle strutture di dati 583 16.1 Liste collegate 583 16.2 Implementare le liste collegate 588 16.2.1 Le classi delle liste, dei nodi e degli iteratori 588 16.2.2 Implementare gli iteratori 589 16.2.3 Implementare l'inserimento e la cancellazione 591 16.3 Stack e code 600 16.4 Altri contenitori standard 603 16.5 Algoritmi standard 604 Riepilogo 606 Letture 606 Esercizi di ripasso 606 Esercizi di programmazione 607 Capitolo 17 C++ avanzato 611 17.1 Overloading degli operatori 611 17.1.1 Funzioni di definizione degli operatori 612 Sintassi 17.1: Definizione dell'overloading dell'operatore 612 17.1.2 Overloading degli operatori di confronto 613 17.1.3 Input e output 613 17.1.4 Overloading degli operatori di incremento e decremento 616 17.1.5 Funzioni membro di overload degli operatori 617 17.2 Gestione automatica della memoria 618 17.2.1 Distruttori 619 Sintassi 17.2: Definizione del distruttore 619 17.2.2 Overloading dell'operatore di assegnazione 620 17.2.3 Costruttori di copie 624 17.2.4 Gestione della memoria per le liste collegate 628 17.3 Modelli 630 Sintassi 17.3: Definizione della classe modello 632 Sintassi 17.4: Definizione della funzione membro modello 633 17.4 Classi nidificate e namespace 640 Sintassi 17.5: Dichiarazione della classe nidificata 641 Sintassi 17.6: Definizione del namespace 643 Sintassi 17.7: Alias del namespace 643 17.5 Gestione delle eccezioni 644 17.5.1 Segnalare le condizioni di errore 644 Sintassi 17.8: Generare un'eccezione 645 17.5.2 Rilevare le eccezioni 646 Sintassi 17.9: Blocco try 647 17.5.3 Gli stack 649 17.5.4 Specifiche per le eccezioni 651 Sintassi 17.10: Specifica per le eccezioni 652 Riepilogo 654 Letture 654 Esercizi di ripasso 654 Esercizi di programmazione 656 Capitolo 18 Interfacce grafiche utente 661 18.1 Il toolkit wxWindows 662 18.2 I frame 663 18.3 Inserire un controllo di testo nel frame 667 18.4 I menu 670 18.5 Gestire gli eventi 672 18.6 Gestire il layout 675 18.7 Disegnare immagini 679 18.8 Gli eventi del mouse 684 18.9 Le finestre di dialogo 688 18.10 Un esempio completo 691 Riepilogo 702 Esercizi di ripasso 703 Esercizi di programmazione 704 Appendice A Guida di stile di programmazione in C++ 705 A.l Introduzione 705 A.2 File sorgenti 706 A.3 Funzioni 708 A.4 Variabili locali 709 A.5 Costanti 709 A.6 Classi 710 A.7 Controllo di flusso 710 A.7.1 Istruzione if 710 A.7.2 Istruzione for 711 A.7.3 Controllo di flusso non lineare 711 A.8 Aspetti lessicali 712 A.8.1 Convenzioni di denominazione 712 A.8.2 Rientri e spazi bianchi 712 A.8.3 Parentesi graffe 713 A.8.4 Impaginazione personalizzata 713 Appendice B Riepilogo del linguaggio C++ e delle librerie 715 B.l Riepilogo delle parole chiave 715 B.2 Riepilogo degli operatori 718 B.3 Sequenze di caratteri escape 720 B.4 Tabella del codice ASCII 721 B.5 Librerie di funzioni standard 722 B.6 Contenitori 726 B.7 Algoritmi ed eccezioni 729 B.8 Libreria proposta da questo volume 731 B.9 Libreria wxWindows 733 Glossario 739 Indice analitico 749 |
| << | < | > | >> |Pagina XIIIPrefazioneQuesto libro offre un'introduzione tradizionale alla scienza informatica utilizzando strumenti attuali. Impostata secondo un punto di vista scientifico, l'attività di programmazione viene presentata in modo accessibile, completo e approfondito. La programmazione è il tema centrale della scienza informatica ed è per questo che qui si insegnerà a programmare. Sebbene questo testo abbia un'impostazione tradizionale, utilizza le tecniche più moderne in tre modi.
* Il linguaggio di programmazione adottato è un subset di C++.
Sebbene C++ sia molto lontano dall'essere un linguaggio didattico, il suo
utilizzo nell'insegnamento ha un significato pragmatico. C++ viene ampiamente
utilizzato nell'industria del software. Ambienti di programmazione pratici ed
economici sono disponibili per tutte le piattaforme principali. C++ è abbastanza
esaustivo da riuscire a trasmettere concetti di programmazione. Questo libro
riduce l'utilizzo di costrutti potenzialmente passibili di errore attraverso
l'impiego di funzionalità più attuali dello standard di C++, come i parametri di
riferimento, la libreria di stream, la classe
string
e il modello
vector * Utilizzo immediato degli oggetti. Gli oggetti vengono introdotti in due fasi. Dal Capitolo 2 in avanti i lettori impareranno a utilizzare gli oggetti, in particolare stringhe, stream, istanze delle classi semplici Time ed Employee e alcune funzioni grafiche. I lettori acquisiranno familiarità con i concetti di creazione degli oggetti e di chiamata delle funzioni membro man mano che il libro prosegue lungo un percorso tradizionale, trattando il branching e i cicli, le funzioni e le procedure. Nei Capitoli 5 e 6 i lettori impareranno a implementare le classi e le funzioni membro. * Utilizzo facoltativo delle funzioni grafiche. A molti utenti potrebbe interessare l'approfondimento degli aspetti legati alla grafica. Questo libro include numerosi esercizi in cui la programmazione tradizionale e quella grafica si rafforzano a vicenda. Per farlo viene utilizzata una libreria grafica molto semplice che è disponibile per diverse piattaforme molto diffuse. A differenza delle librerie grafiche tradizionali, questa utilizza gli oggetti in modo molto diretto ed efficace. L'utilizzo di questa libreria è facoltativo. Il Capitolo 8 contiene un'introduzione alla programmazione di interfacce grafiche utente mediante l'impiego di un toolkit open-source (utilizzabile gratuitamente) simile alla libreria Microsoft Foundation Class.
La scelta del linguaggio di programmazione ha un notevole impatto
sull'efficacia didattica di qualsiasi libro che affronti l'argomento. Lo scopo
di questo libro è tuttavia quello di insegnare concetti informatici e non tutti
i dettagli di C++. Questo linguaggio viene utilizzato come strumento per
padroneggiare i fondamenti della scienza informatica.
Impostazione pedagogica Ogni capitolo inizia con una panoramica degli obiettivi trattati e un'introduzione a supporto. I capitoli sono disseminati di cinque tipi di note che aiutano il lettore, chiamate Errore comune, Suggerimento, Consiglio, Approfondimento e Curiosità. Queste note sono segnalate in modo da non interrompere il flusso del materiale principale. Alcune note sono brevi, altre occupano più pagine e hanno lo scopo di rendere più completa e convincente la spiegazione degli argomenti. | << | < | > | >> |Pagina 243Programmazione: arte o scienza? Si discute tanto sul fatto che lo studio dei computer debba essere o meno considerato una scienza. La considerazione che questo ambito di studio venga chiamato scienza informatica non sembra particolarmente significativa; poche persone, con l'eccezione forse di bibliotecari e sociologi, possono ritenere che le scienze bibliografiche e le scienze sociali siano settori scientifici a tutti gli effetti. Una disciplina scientifica si propone l'obiettivo di scoprire determinati concetti fondamentali che rispettino le leggi naturali e si basa sul metodo scientifico: si pongono ipotesi che vengono verificate mediante esperimenti riproducibili da altri operatori del settore. Per esempio, un fisico può sviluppare una sua teoria sulla nascita delle particelle nucleari e il tentativo di confermare o smentire questa teoria può essere condotto mediante esperimenti con l'acceleratore di particelle. Se un esperimento non viene verificato, la teoria è destinata a una morte prematura, come nel caso della ricerca sulla fusione fredda sviluppata nei primi anni '90 nell'Università dello Utah. A dire il vero può capitare anche ai programmatori di eseguire esperimenti. Si possono provare diverse procedure di calcolo per ottenere determinati risultati, oppure si possono configurare diversi sistemi operativi misurando le prestazioni che si ottengono. In ogni caso l'obiettivo principale non ha comunque niente a che vedere con la scoperta di nuove leggi della natura. Alcuni scienziati informatici scoprono l'esistenza di concetti fondamentali. Una categoria di questi risultati afferma per esempio che è impossibile scrivere tipi particolari di programmi, a prescindere dalla potenza del computer utilizzato. Per esempio, è impossibile scrivere un programma che possa leggere due file di programmi C++ qualsiasi e produca un output in grado di stabilire se questi due programmi ottengono sempre risultati identici fra loro. Un programma di questo tipo sarebbe molto comodo per valutare i compiti degli studenti ma nessuno, non importa quanto possa essere bravo, sarà mai in grado di scrivere un programma che possa funzionare correttamente con tutti i file in input. Va aggiunto inoltre che la maggior parte dei programmatori scrive programmi e non si preoccupa di investigare i limiti che il calcolo con il computer presenta. Ci sono persone che considerano la programmazione una specie di arte o maestria. Un programmatore che sappia scrivere in modo elegante codice che sia facile da leggere e funzioni con un ottimo livello di efficienza può effettivamente essere considerato un valido artigiano del settore. Da qui a parlare di arte ce ne corre, dato che un oggetto artistico richiede la presenza di un pubblico in grado di apprezzarne le qualità: in genere il codice di un programma non viene nemmeno visto dall'utente del programma. Ci sono poi quelli che considerano lo studio dei computer una disciplina a carattere ingegneristico. Così come l'ingegneria meccanica si basa su concetti matematici fondamentali di statica, anche per i computer è possibile definire una serie di concetti fondamentali di tipo matematico. Nell'ingegneria meccanica si ritrova comunque qualcosa che va oltre la matematica, per esempio la conoscenza dei materiali e la pianificazione dei progetti; lo stesso si può dire per lo studio dell'informatica. Da un certo punto di vista, lo studio dell'informatica non dispone delle stesse basi presenti in altre discipline ingegneristiche. Non c'è uniformità di vedute rispetto a quello che si deve considerare una condotta professionale nel settore dei computer. A differenza dello scienziato vero e proprio, la cui responsabilità principale è legata alla ricerca della verità, l'ingegnere deve fronteggiare esigenze in conflitto tra loro che fanno riferimento a qualità, sicurezza e costi del proprio lavoro. Le discipline a carattere ingegneristico prevedono la presenza di organismi professionali che stabiliscono per i propri associati una serie di comportamenti standard. Il settore dei computer è relativamente nuovo e in molti casi non si conosce ancora la procedura corretta che permette di raggiungere determinati risultati con la massima efficienza. Tutto ciò rende difficile la definizione di standard professionali. Che cosa si può dedurre da questo ragionamento? In base alla propria esperienza, come è meglio considerare la disciplina informatica: un'arte, un mestiere, una scienza oppure un'attività ingegneristica? | << | < | > | >> |Pagina 47313 Design orientato agli oggettiObiettivi didattici Gli argomenti affrontati in questo capitolo sono: * analisi del ciclo di vita del software; * esame delle classi e delle funzioni membro; * la coesione e il coupling; * metodo della scheda CRC; * comprensione dei diagrammi di classe UML; * utilizzo del design orientato agli oggetti per creare programmi complessi; * studio degli esempi del processo di design orientato agli oggetti. Per implementare un sistema di software con successo, semplice come un lavoro preparatorio o complesso come un sistema di monitoraggio del traffico aereo, è necessario pianificare, progettare e testare. In realtà, per i progetti più ampi, è necessario dedicare molto più tempo alla pianificazione piuttosto che alla stesura del codice e all'esecuzione del test.
Se nel lavoro di sviluppo si trascorre la maggior parte del tempo davanti al
computer a codificare e a correggere gli errori, probabilmente è perché vi si
dedicano troppe ore. Si potrebbe ridurre il tempo complessivo pensando più alla
fase di pianificazione e di design. Questo capitolo esamina come affrontare
questi compiti in modo sistematico.
13.1 Il ciclo di vita del software In questo paragrafo si esaminerà il ciclo di vita del software: le attività che si svolgono tra la fase di ideazione iniziale del programma di software e la fase di ritiro definitivo dal commercio. Molti progettisti di software suddividono il processo di sviluppo nelle cinque fasi seguenti: * analisi * design * implementazione * test * installazione Nella fase di analisi, si decide cosa si ritiene che il progetto debba attuare; non si pensa al dettaglio di come il programma realizzerà i suoi compiti. L'output della fase di analisi è un documento dei requisiti, che descrive nei dettagli ciò che il programma sarà in grado di portare a termine. Una parte di questo documento può essere un manuale utente che spiega il funzionamento del programma affinché l'utente possa trarre i benefici promessi. Un'altra parte imposta i criteri delle prestazioni: quanti input il programma deve essere in grado di gestire e in quanto tempo, o la memoria massima e i requisiti della memorizzazione su disco. Nella fase di design, si sviluppa un progetto per implementare il sistema. Si descrivono le strutture di dettaglio per il problema da risolvere. Se si utilizza il design orientato agli oggetti, si stabilisce quali classi occorrono e le loro funzioni membro più importanti. L'output di questa fase è una descrizione delle classi e delle funzioni membro, contenente diagrammi che mostrano le relazioni tra le classi. Nella fase di inplementazione, si scrive e si compila il codice del programma per implementare le classi e le funzioni membro esaminate nella fase di design. L'output di questa fase è il programma completato. Nella fase di test, si eseguono i collaudi necessari per verificare che il programma funzioni correttamente. L'output di questa fase è un rapporto che descrive i test eseguiti e i loro risultati. Nella fase di installazione, gli utenti installano e utilizzano il programma per lo scopo previsto. Quando si gestisce un grande progetto software, l'organizzazione di queste fasi non è ovvia. Un responsabile deve sapere quando porre fine all'analisi e iniziare il design, quando porre fine alla codifica e iniziare l'esecuzione del test e così via. Nella gestione dei progetti software si istituiscono le procedure formali. Una procedura formale individua le attività e i risultati delle diverse fasi e indica le linee guida di attuazione delle fasi e di passaggio da una all'altra. Quando le procedure di sviluppo formali furono istituite per la prima volta all'inizio degli anni '70, i progettisti dei software si attenevano a un semplicissimo modello visuale di queste fasi. Postulavano che una fase si sarebbe eseguita fino al termine, il suo output si sarebbe riversato sulla fase successiva e quest'ultima sarebbe iniziata. Questo modello viene definito modello a cascata dello sviluppo dei software (Figura 13.1). In un mondo ideale il modello a cascata è affascinante: si immagina cosa fare, si pensa a come farlo, lo si realizza, si verifica di averlo fatto bene e si consegna il prodotto al cliente. Tuttavia se questo modello fosse applicato rigidamente non funzionerebbe. Era molto difficile elaborare una specifica perfetta dei requisiti. Nella fase di design era piuttosto frequente scoprire che i requisiti non erano coerenti o che una loro piccola modifica avrebbe generato un sistema più facile da progettare e più utile per il cliente; tuttavia l'analisi della fase era conclusa e i progettisti non avevano altra scelta: dovevano considerare come validi i requisiti esistenti, gli errori e tutto il resto. Questo problema si ripeteva durante l'implementazione. I progettisti potevano anche credere di risolvere il problema nel modo più efficiente possibile, ma quando il design era effettivamente implementato, il programma creato non si dimostrava così veloce come avevano ipotizzato. La transizione successiva è certamente nota. Quando il programma veniva consegnato al dipartimento di verifica della qualità per l'esecuzione dei test, si scoprivano molti errori che sarebbero stati corretti meglio implementando oppure addirittura riprogettando il programma; tuttavia il modello a cascata non lo consentiva. Infine quando i clienti ricevevano il prodotto ultimato, non ne erano affatto soddisfatti. Anche se essi di solito erano coinvolti nella fase di analisi, spesso non erano certi di quello che gli occorreva. In fin dei conti può essere molto difficile descrivere come si vuole utilizzare un prodotto che non si è mai visto prima. Tuttavia quando i clienti iniziavano a utilizzare il programma, si rendevano conto di cosa avrebbero voluto. Ovviamente era troppo tardi e dovevano tenersi ciò che avevano in mano. Disporre di un livello di iterazione è ovviamente necessario. Deve essere semplicemente presente un meccanismo per affrontare gli errori della fase precedente. Il modello a spirale, proposto da Barry Boehm nel 1988, suddivide il processo di sviluppo in varie fasi (Figura 13.2).
Le fasi iniziali si concentrano sulla costruzione dei
prototipi.
Un prototipo è un piccolo sistema che mostra alcuni aspetti del sistema finale.
Dal momento che i prototipi modellano solo una parte del sistema e non devono
resistere all'uso improprio dei clienti, possono essere implementati
rapidamente. È comune costruire un
prototipo di interfaccia utente
che mostra l'interfaccia utente in azione. Esso offre ai clienti la possibilità
di familiarizzare maggiormente con il sistema e di suggerire i miglioramenti
prima della conclusione dell'analisi.
È possibile costruire altri prototipi per convalidare le interfacce con i
sistemi esterni, per testare le prestazioni e così via. Le lezioni apprese dallo
sviluppo di un prototipo possono essere applicate all'iterazione successiva
della spirale.
Incorporando prove ripetute e riscontri da parte del cliente, una procedura di
sviluppo che segue il modello a spirale ha una possibilità maggiore di generare
un sistema soddisfacente. Tuttavia è presente anche un rischio. Se i progettisti
ritengono di non dover svolgere un buon lavoro perché possono sempre compiere
un'altra iterazione, ci saranno sempre troppe iterazioni e la procedura
richiederà molto tempo prima di giungere al termine.
|