lunedì 30 dicembre 2013

Uso dei modelli

Quando si scrive un articolo, è necessario trovare un modello adatto da seguire. Piuttosto che cercare di trovare articoli che trattano lo stesso argomento. Bisogna trovare una struttura adatta all'argomento trattato. In questo modo è possibile modificare il testo in modo da aggiungere frasi, informazioni e dettagli in modo logico, senza dover alterare la struttura di tutto l'articolo. L'uso di sistemi già esistenti per realizzare nuovi progetti è la norma piuttosto che l'eccezione in tutte le forme di costruzione creativa. Quando è possibile, la progettazione e la programmazione devono essere basate su lavori precedenti. I limiti di questa libertà consente al programmatore di basare la propria attenzione solo su pochi argomenti alla volta. Iniziare un progetto principale, “dalla bozza su carta” può essere divertente. Comunque spesso una descrizione più attenta di questo fenomeno è “ubriacante” e il risultato conduce a progetti alternativi lasciati a metà. Avere un modello non è una costrizione e non richiede che il modello sia seguito fedelmente; libera semplicemente il designer dal considerare un aspetto del progetto alla volta.
L'uso dei modelli è inevitabile, in quanto il progetto verrà sintetizzato dall'esperienza di tutti i progettisti. Avere un modello esplicito rende la scelta di un modello una decisione cosciente, fa assunzioni esplicite, definisce un vocabolario comune, fornisce una struttura iniziale per il progetto, e aumenta la probabilità dei progettisti di ottenere un comune approccio. Naturalmente la scelta del modello iniziale è un passo importante in fase di progettazione e spesso può essere fatto solo dopo una ricerca di modelli potenziali e attenta valutazione delle alternative. Inoltre in molti casi è adattabile solo dopo una comprensione delle modifiche necessarie per adattarlo alle idee particolari della nuova applicazione.
La progettazione del software è complessa, bisogna cercare maggior aiuto possibile. Non bisogna rifiutare l'uso di modelli con sdegno liquidandoli come “imitazioni”. L'imitazione è una forma di appiattimento, ma l'uso di modelli provenienti da precedenti lavori è d'ispirazione, nei confini definiti dalla legge del copyright, è una tecnica innovativa che funziona in tutte le arre di lavoro. Alcuni definiscono questo uso di modelli come “riuso del progetto”.
E' una buona idea per il progettista conoscere tutte le soluzioni popolari esistenti per una cerca applicazione. Come programmatore si preferisce le soluzioni che abbiano del codice associato ad esse come esempio concreto. Le persone che usano delle soluzioni standard spesso usano un vocabolario specializzato per comunicare tra loro stesse.

Sfortunatamente questo può diventare un linguaggio privato che tende ad escludere degli estranei dalla comprensione; è essenziale assicurare una comunicazione adatta tra le persone coinvolte nelle diverse parti del progetto, e anche con la comunità dei progettisti e programmatori nell'insieme. Ogni sistema di grandi dimensioni che ha successo è la ri-progettazione di un sistema di minori dimensioni. Non esistono eccezioni a questa regola. L'esempio più prossimo che si possa fare è quello di sistemi che hanno fallito e sono rimasti impanatati per anni con grandi costi, poi eventualmente sono diventati successi negli anni successivi alla loro data di completamento. Questi progetti casualmente e spesso inavvertitamente, hanno dapprima costruito una rete di sistemi non funzionanti, quindi sono stati trasformati in un sistema funzionante, e finalmente la ri-progettazione ha raggiunto gli scopi iniziali. Questo implica che è una follia progettare grandi sistemi direttamente dalla bozza. Maggiori sono le dimensioni del sistema da costruire, maggiore importanza avrà il modello con il quale si lavora. E per sistemi di grandi dimensioni, il solo modello accettabile deve essere un sistema più piccolo ma funzionante e simile ad esso.

giovedì 29 agosto 2013

Il ciclo di Sviluppo

Sviluppare un sistema è un'attività iterativa. Il suo ciclo principale è formato da ripetuti passi attraverso la sequenza:
  1. Esaminare il problema;
  2. Creare un progetto generale;
  3. Trovare componenti standard (e personalizzarli per il progetto);
  4. Creare nuovi componenti standard (personalizzarli per il progetto);
  5. Costruire il progetto.

L'analogia da usare, è la linea di assemblaggio di un'auto. Per il progetto in generale, deve esistere il design della nuova auto da creare. Poi si passa alle caratteristiche da fornire alla nuova auto definendone le proprietà nel dettaglio. Decidere quali proprietà sono volute, o fornire una linea guida di quali proprietà si vuole ottenere. Se ben realizzata questo tipo di lavoro viene svolto da una sola persona illuminata, e spesso viene chiamata vision. E' abbastanza comune per progetti privi di obbiettivi chiari di fallire per l'una o l'altra ragione. Il primo passo da considerare è quali componenti sono disponibili nell'inventario aziendale, o acquistabili da fornitore. I componenti trovati devono quindi trovare posto nella realizzazione della nuova auto, ma posso anche non essere del tutto adatti. Tuttavia si può pensare che “al successivo lancio”, i componenti saranno stati modificati per adattarsi all'auto. Ad esempio si può trovare un motore delle dimensioni adatte, ma che sia di potenza minorata. Il fornitore del motore potrebbe aggiungere una turbina per compensare alla potenza mancante, ma ciò non deve influenzare il disegno di base del motore.Nel caso dello sviluppo del software le classi polimorfiche e i templates sono utilizzati come componenti personalizzabili. Tuttavia non è facile creare estensioni arbitrarie a queste classi senza previsione o cooperazione da parte del gestore di queste classi. Da notare che questo modello di sviluppo funziona solo quando si ragiona a lungo termine; se il vostro orizzonte riguarda solo il prossimo rilascio del software, la creazione e la manutenzione delle componenti standard non ha senso. Questo tipo di organizzazione riguarda compagnie la cui vita abbia la durata di molti progetti, le cui dimensioni richiedano l'investimento in questa attrezzatura extra (per la progettazione, programmazione, gestione dei progetti) e formazione ( di programmatori, progettisti e manager). Si tratta di una struttura base di una fabbrica di software. Inoltre i componenti standard non possono essere considerati come universali. Puntare all'universalità in un progetto iniziale è la ricetta sicura per il fallimento; uno dei motivi per la creazione del ciclo di sviluppo è quello di ottenere esperienza.

giovedì 22 agosto 2013

Il processo di Sviluppo

Lo sviluppo del software è un processo iterativo ed incrementale. Ogni passo del processo è rivisto ripetutamente durante lo sviluppo, ed ogni revisione rifinisce il prodotto finale. In generale, il processo non ha un inizio ed una fine. Quando si progetta e implementa un sistema, si comincia da una base formata da librerie, progetti e applicazioni scritte da altri. Quando si finisce si lascia il grosso della progettazione e del codice ad altri per essere rifinito, e portato su altri sistemi. Naturalmente ogni progetto specifico ha un inizio e un termine, ciò è importante per definirne l'obiettivo e le dimensioni nel tempo. Comunque la pretesa di cominciare da zero può causare seri problemi. Inoltre la pretesa di una data di consegna inderogabile causa seri problemi ai propri successori. Il processo di sviluppo è formato da tre livelli:
  • Analisi, definire l'obiettivo del problema da risolvere
  • Progettazione, creare una struttura generale del sistema
  • Implementazione, scrivere e verificare il codice
Si ricordi la natura iterativa di questo processo, in quanto i tre livelli non sono in ordine: Da notare che alcuni aspetti maggiori del programma di sviluppo non sono in livelli separati perché si tratta di processi pemeabili tra loro.
  • Sperimentazione
  • Verifica con test
  • Analisi della progettazione ed implementazione
  • Documentazione
  • Gestione

La “gestione” del software è quella che ha maggiori iterazioni nel processo di sviluppo; è importante che analisi, progettazione ed implementazione non siano troppo staccate tra loro nel programma di sviluppo, e le persone coinvolte condividano le proprie conoscenze e comunichino effettivamente. In progetti di grandi dimensioni, spesso non accade. Gli individui si spostano da un livello all'altro durante il progetto, il solo modo di trasferire queste informazioni è la testa delle persone. Tuttavia le compagnie tendono a creare delle barriere tra i progettisti di maggiore calibro come protezione dal licenziamento, e per esempio, coloro che sono semplici programmatori. Le persono dovrebbero essere incoraggiate a condividere le informazioni tra loro, attraverso una etichetta con un grado di formalità appropriato.

sabato 17 agosto 2013

Scopi e obbiettivi

L'obiettivo di un programmatore professionista è consegnare un prodotto che soddisfa i suoi utenti. Il principale significato è produrre un programma dotato di una chiara struttura interna che possa crescere grazie ad un gruppo di programmatori abili e abbastanza motivati per rispondere in modo rapido alle opportunità ed ai cambiamenti.
Perché? La struttura interna di un programma e il processo con il quale viene creato non ha effetto sull'utente. Quindi che importanza può avere la struttura interna del programma per chi scrive il software.
Un programma ha bisogno di una struttura interna chiara, per gestire meglio:
  • testing (prove funzionali)
  • porting (adattare ad altri sistemi)
  • manutenzione
  • riorganizzazione e
  • comprensione
La maggiore importanza per un software di successo è data dalla vita d'uso, estesa da una serie di programmatori e progettisti, adattato per nuovo tipo di hardware, modificato per nuove applicazioni e riorganizzato ripetutamente. Nessuna pianificazio per questo implica il fallimento. Non solo un utente non vuole conoscere la struttura interna del programma, ma non vuole neppure pensare ad essa. Un punto di equilibrio deve essere raggiunto tra la mancanza di un design in generale per un frammento di software e una struttura troppo enfatizzata. La priam porta a preoccuparsi di smussare gli spigoli (“usa questo, correggeremo i bug nella prossiam versione”). La seconda porta a ritardi nella consegna a caqusa di una sovraorganizzazione nel progetto (“la nuova struttura è meglio della procedente, la gente aspetterà”). Inoltre spesso si ottiene qulacosa che richiede risorse che l'utente non riesce a dare. Le scelte da fare sono difficili, e per progetti di dimensioni maggiori diventano sempre più difficili. Un programma deve essere prodotto e gestito da una organizzazione, in modo che nonostante i cambi del personale, direzione e struttura di management non possa influenzarlo. Un approccio molto usato dalle aziende è creare una classe di programmatori facili da addestrare a basso livello “coders”, e una classe di programmatori facili da sostituire anche se meno economici “designers”. Tuttavia questo approccio fallisce in quanto tende a creare sistemi di grandi dimensioni con scarse performance.
I problemi di questo approccio sono:
  • comunicazione insufficiente tra codificatori e progettisti, che producono opportunità mancate, ritardi, inefficienze e problemi per mancanza di esperienza;
  • poca focalizzazione per i codificatori, mancanza di crescita professionale, stanchezza e alto cambio di personale.

Principalmente, questo sistema manca di un meccanismo di ritorno che permette alle persone di beneficiare dell'esperienza degli altri. E' uno spreco del talento umano. Creare una struttura dove le persone possano usare il loro talento, sviluppare nuove abilità, contribuire alle idee e divertirsi nonè solo uan cosa decente da fare, ma ha anche senso economico.

domenica 11 agosto 2013

Design con il C++ II

Si prega di ricordare la straordinaria diversità delle aree di applicazione e degli ambienti di sviluppo. Le osservazioni sono fatte su progetti reali e si applicano ad un'ampia varietà di situazioni, ma non possono essere considerate universali. Pertanto guardate a queste osservazioni con un certo grado di scetticismo. C++ può essere utilizzato come un C migliorato, tuttavia questo approccio lascia le tecniche più potenti e caratteristiche del linguaggio inutilizzate, in modo da guadagnare solo una piccola frazione dei benefici potenziali dall'uso del C++. In questo capitolo ci si focalizza sugli approcci al design che permettono di usare le astrazioni dati e la programmazione orientata agli oggetti del C++; tali tecniche sono chiamate programmazione orientata agli oggetti.
I maggiori argomenti di questo capitolo sono:
  • La cosa più importante da tenere a mente nello sviluppo del software è sapere chiaramente che cosa si vuole costruire.
  • Lo sviluppo di software di successo è attività a lungo termine.
  • I sistemi che costruiamo tendono ad essere limitati dalla complessità che noi o il nostro strumento può gestire.
  • Non esiste un manuale che possa sostituire l'intelligenza, esperienza e il buon gusto nella programmazione e design.
  • La sperimentazione è necessaria per lo sviluppo di software non triviali
  • Programmazione e design non possono essere considerati senza tener conto della gestione pianificata di queste attività.

E' facile e costoso sotto-stimare questi punti. E' difficile trasformare delle idee astratte in qualcosa da mettere in pratica. Si noti il bisogno di esperienza. Così come costruire mobili, biciclette, la programmazione non è un'abilità che può essere dominata senza uno studio teorico da solo. Spesso, noi umani dimentichiamo gli aspetti della costruzione dei sistemi e consideriamo lo sviluppo del software una serie di passi ben definiti, per ognuna delle quali vi sono delle azioni specifiche e degli input, il quale produce in base ad una serie di regole degli output. Design e programmazione sono attività umane; dimenticare questo e si perde tutto. Questo capitola si occupa della progettazione di vari sistemi che sono relativi all'esperienza e alle risorse delle persone che costruiscono il sistema. E' nella natura delle persone affrontare progetti che raggiungono i limiti della loro abilità. Progetti che non offrono sfide, non sono considerati come design. Solo quando qualcosa di ambizioso viene tentato si sente il bisogno di creare nuovi strumenti ed affrontare nuove tecniche. Ma c'è anche la tendenza ad assegnare progetti peri quali “sappiamo come fare” a novizi che non lo sanno. Chiaramente queste cose riguardano lo sviluppano di software di grandi dimensioni; i lettori che non sono coinvolti in tale sviluppo possono sedersi e godersi la descrizioni degli orrori da evitare. In alternativa possono guardare un sottoinsieme delle discussioni relative al lavoro individuale; non esiste un limite inferiore nella dimensione dei programmi per il quale esiste un particolare approccio alla documentazione e al design. Il problema fondamentale nello sviluppo del software è la complessità, esiste un solo modo per gestire la complessità: dividi et impera. Un problema può essere separato in sotto-problemi che possono essere maneggiati, questo semplice principio si applica in molti modi. In particolare se si usa un modulo o una classe nel design di sistemi separati del programma, che vengono connessi tramite una interfaccia be definita. Questo approccio fondamentale nella gestione dei problemi, in maniera simile viene fatto nella fase di progettazione del programma, la quale può essere idealmente divisa in iterazioni ben definite tra le persone coinvolte. Questo è l'approccio di base per al gestione di problemi di complessità inerente al processo di sviluppo e alla gente coinvolta.

sabato 10 agosto 2013

Design con il C++

Costruire un software non triviale può essere un compito difficile e complesso da realizzare. Anche per il singolo programmatore, la creazione delle procedure reali del programma è solo un parte del processo. Tipicamente, l'analisi del problema, sovrasta il design del programma, la documentazione, testing e manutenzione. Così come la gestione di tutto questo, è ben poco se comparata al lavoro di scrittura e debug del singolo frammento di codice. Naturalmente, uno può pensare che la totalità di queste attività sono “programmazione”, e quindi giungere alla conclusione che “Io non faccio design, io programmo” ma comunque sia chiamata questa attività, è importante focalizzarsi sia sulle piccole parti che sul programma in generale. I singoli dettagli, come il quadro in generale non devono essere persi di vista, anche nella fretta di consegnare il prodotto, tuttavia spesso è ciò che accade. In questo capitolo ci focalizzeremo sulle parti di sviluppo del programma che non coinvolgono direttamente la scrittura e il debug delle singole parti di codice. La discussione è meno precisa e dettagliata di come discutere sulle singole caratteristiche del linguaggio e le specifiche tecniche di programmazione presentate altrove in questo libro. Tuttavia è necessario perché non esiste un ricettario capace di dare un metodo per creare del buon software.
Tipologie dettagliate di “Come fare...” esistono per applicazioni già bene definite, ma non per applicazioni in generale. Non esiste alcun sostituto all'intelligenza, esperienza, e istinto nella programmazione. Di conseguenza questo capitolo offre solo consigli in generale e approcci alternativi, insieme a caute osservazioni.

La discussione è guidata dalla natura astratta del software, per cui scrivere un programma di piccole dimensioni (circa 10.000 linee di codice) richiede tecniche, che difficilmente possono essere applicate per progetti medio/larghi. Per questo motivo, alcune discussioni sono formulate in termini di analogie con discipline ingegneristiche meno astratte piuttosto che in termini di codice. Discussioni sulle questioni di design in termini di C++ sono presentati nei successivi capitoli. Le idee espresse in questo capitolo sono riflessi sia dal linguaggio C++ e dalla presentazione di esempi individuali attraverso il blog.

martedì 7 maggio 2013

Specificare i vertici

Con OpenGL tutti gli oggetti geometrici sono descritti in termini di vertici raggruppati ordinatamente. Si usa il comando glVertex*() per specificarlo.
void glVertex{2 3 4}{sifd}[v](coordinate);
Specifica un vertice come oggetto geometrico. Si possono fornire le coordinate (x,y,z,w) per un vertice in particolare o per pochi selezionando una versione appropriata del comando. Se si sua una versione che non specifica esplicitamente z o w, essi sono intesi con un valore pari a 0 e 1. La chiamata di glVertex*() sono solo utilizzabili tra le istruzioni glBegin() e glEnd().
glVertex2s(5,6);
glVertex3d(1.0,1.0, 3.1415);
Gldouble dvettore[3] = { 4.0, 5.0, 29.0};
glVertex3v(dvettore);

Nella prima istruzione vien specificato un vertice le cui coordinate appartengono allo spazio bidimensionale (x,y). Nella seconda istruzione viene specificato un vertice le cui coordinate appartengono ad uno spazio tridimensionale (x,y,z). Nelle istruzioni successive si definisce un vettore di coordinate tridimensionali, le quali sono passate come argomento all'istruzione glVertex3v per la definizione di una serie di vertici, nell'esempio vengono definite solo le coordinate del primo vertice.