Copertina
Autore Cay Horstmann
Titolo Fondamenti di C++
EdizioneMcGraw-Hill, Milano, 2003, workbooks , pag. 768, cop.fle., dim. 167x240x33 mm , Isbn 978-88-386-6105-1
OriginaleComputing Concepts with C++ Essentials [2003]
LettoreCorrado Leonardo, 2004
Classe informatica: linguaggi
PrimaPagina


al sito dell'editore


per l'acquisto su IBS.IT

per l'acquisto su BOL.IT

per l'acquisto su AMAZON.IT

 

| << |  <  |  >  | >> |

Indice

Prefazione                                 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 XIII

Prefazione

Questo 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. I puntatori vengono utilizzati principalmente per il polimorfismo e l'implementazione di liste collegate.

* 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 243

6.1 Curiosità



Programmazione: 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 473

13 Design orientato agli oggetti


Obiettivi 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.

| << |  <  |