• Non ci sono risultati.

Non riscrivere il codice esistente in C++

Nel documento Pensare in C++, seconda ed. Volume 1 (pagine 44-49)

Fase 5: Evoluzione

5. Non riscrivere il codice esistente in C++

Sebbene compilare il codice C con un compilatore C++ produce di solito ( a volte tremendi) benefici per trovare i problemi del vecchio codice, di solito non conviene prendere codice esistente e funzionale per riscriverlo in C++ ( bisogna trasformarlo in oggetti, si può inglobare il codice C in classi C++). Ci sono dei benefici, specialmente se il codice deve essere riusato. Ma ci sono possibilità che non si vedano i grossi incrementi di produttività che si speravano, fino a che il progetto non parta da capo. il C++ e la OOP brillano di più quando si porta un progetto dall'idea alla realtà.

Il Management ostacola

Se si è un capo, il proprio lavoro è quello di acquisire risorse per la propria squadra, superare le barriere che impediscono alla squadra di avere successo ed in generale creare l'ambiente più produttivo e gradevole che sia possibile affinché la propria squadra possa fare quei miracoli che di solito vengono chiesti. Passare al C++ ha riflessi in tutte e tre queste categorie e sarebbe davvero meraviglioso se non costasse qualcosa. Sebbene il

passaggio al C++ possa essere più economico,in dipendenza da vincoli[23] che si hanno

con altre alternative OOP per una squadra di programmatori in C (e probabilmente per programmatori in altri linguaggi procedurali), non è del tutto gratuito e vi sono ostacoli che si farebbe bene a conoscere prima di promuovere il passaggio al C++ all'interno della propria società imbarcandosi nel passaggio vero e proprio.

Costi di partenza

Il costo del passaggio al C++ è molto più che la semplice acquisizione di compilatori C++ (il compilatore GNU C++ è gratuito, quindi non è certo un ostacolo). I costi di medio e lungo periodo si ridurranno al minimo se si investirà in addestramento (e magari

in una consulenza per il primo progetto) e se inoltre si individuerà e si acquisterà librerie di classi che risolvono il proprio problema, piuttosto di tentare di costruire quelle librerie. Questi sono costi in denaro contante, che vanno conteggiati in una proposta realistica. Inoltre, vi sono costi nascosti che derivano dalla perdita di produttività mentre si impara un nuovo linguaggio ed eventualmente un nuovo ambiente di programmazione.

Addestramento e consulenza possono certamente ridurre al minimo questi costi, ma i componenti della squadra devono superare le loro difficoltà nel capire la nuova tecnologia. Durante questo processo faranno un maggior numero di sbagli (e questo è un vantaggio, perché gli sbagli riconosciuti sono la via più rapida per l'apprendimento) e saranno meno produttivi. Anche in questi casi, almeno per determinati tipi di problemi di

programmazione, disponendo delle classi giuste e con un ambiente di sviluppo adeguato, è possibile essere più produttivi mentre si impara il C++ (pur tenendo conto che si fanno più sbagli e si scrivono meno righe di codice al giorno) di quanto non sarebbe se si restasse col C.

Problemi di prestazioni

Una domanda molto diffusa è: "Non è che l'OOP renda automaticamente i miei

programmi molto più voluminosi e più lenti?"La risposta è: "Dipende". Le maggior parte

dei linguaggi OOP tradizionali sono stati progettati per scopi di sperimentazione e

prototipazione rapida. Quindi essi virtualmente garantiscono un significativo incremento in dimensioni ed una diminuzione di velocità. Il C++, tuttavia, è progettato per la

produzione. Quando lo scopo è la prototipazione rapida, si possono mettere insieme

componenti il più velocemente possibile ignorando i problemi di efficienza. Se si utilizzano librerie di terzi, di solito esse saranno già state ottimizzate dai loro fornitori; in tutti i casi, questo non è un problema quando si lavora in una prospettiva di sviluppo rapido. Quando si ha un sistema che piace, se è sufficientemente piccolo e veloce, non serve altro.

Altrimenti, si comincia a ritoccarlo con uno strumento di profilatura, cercando in primo luogo possibili accelerazioni che si potrebbero ottenere riscrivendo piccole parti del codice. Se questo non basta, si cercano le modifiche che si possono apportare all'implementazione sottostante, in modo che non si debba cambiare il codice che utilizza una classe particolare. Soltanto se nient'altro risolve il problema si ha bisogno di modificare la progettazione. Il fatto che le prestazioni siano così critiche in quella parte della progettazione fa capire che devono entrare a far parte dei criteri primari della progettazione. Con lo sviluppo rapido si ha il vantaggio di accorgersi molto presto di questi problemi.

Come menzionato prima, il numero che è più spesso dato per la differenza in dimensioni e velocità tra C e C++ è ±10% e spesso molto prossimo alla parità. Si può persino ottenere un significativo miglioramento in dimensioni e velocità quando si usa il C++ piuttosto che il C perchè il progetto che si fa in C++ potrebbe essere molto diverso da quello che si farebbe in C.

L'evidenza nelle comparazioni di dimensioni e velocità tra C e C++ tende ad essere

aneddotica e a rimanere probabilmente così. Malgrado il numero di persone che suggerisce ad un'azienda di provare a sviluppare lo stesso progetto usando C e C++, nessuna di esse spreca denaro così, a meno che non è molto grande ed interessata in tali progetti di ricerca. Persino in questo caso, sembra che ci sia un modo migliore di spendere il denaro. Quasi

universalmente, i programmatori che sono passati dal C ( o qualche altro linguaggio procedurale) al C++ ( o qualche altro linguaggio OOP) hanno avuto l'esperienza personale di una grande accelerazione nella loro produttività e questo è il miglior argomento che si possa trovare.

Errori comuni di progettazione

Quando un team comincia a lavorare con l'OOP ed il C++, i programmatori di solito commettono una serie di comuni errori di progettazione. Ciò accade spesso a causa del limitato contributo degli esperti durante il progetto e l'implementazione dei primi progetti, poichè nessun esperto ha sviluppato nell'azienda e ci può essere resistenza ad acquisire consulenti. È facile avere troppo presto la sensazione di aver capito l'OOP e di andar via per la tangente. Qualche cosa che è ovvio per qualcuno che ha esperienza con il linguaggio può essere un soggetto di un grande dibattito interno per un novizio. Questo trauma può essere evitato usando l'esperienza di un esperto esterno per l'addestramento ed il

mentoring.

Dall'altro lato, il fatto che è facile commettere questi errori di disegno indica i principali svantaggi del C++: la sua compatibilità all'indietro con il C ( naturalmente, questa è anche la sua forza principale). Per realizzare l'impresa di compilare un codice C, il linguaggio ha dovuto fare qualche compromesso, che consiste in qualche punto oscuro: essi sono una realtà e constituiscono le maggiori difficoltà per l'apprendimento del linguaggio. In questo libro e nel volume seguente ( ed gli altri libri, si veda l'Appendice C), si cercherà di rivelare la maggior parte delle insidie che si incontrano quando si lavora con il C++. Bisognerebbe essere sempre consapevoli che ci sono dei buchi nella rete di sicurezza.

Sommario

Questo capitolo cerca di dare un'idea dei vari argomenti della programmazione orientata agli oggetti, incluso il perchè la OOP è qualcosa di diverso e perchè il C++ in particolare è diverso, presentando concetti delle metodologie OOP ed infine i tipi di problematiche che si incontreranno quando la propria azienda comincerà ad usare la OOP ed il C++.

La OOP ed il C++ possono non essere per tutti. È importante valutare i propri bisogni e decidere se il C++ soddisferà in maniera ottimale quelle necessità o se è migliore un altro sistema di programmazione ( incluso quello che si sta utilizzando correntemente). Se si sa che le proprie necessità saranno molto specializzate per il fututo e si hanno dei vincoli specifici che potrebbero non essere soddisfatti dal C++, allora bisogno investigare su

possibili alternative[24]. Anche se alla fine si sceglie il C++ come linguaggio, si capiranno

almeno quali sono le opzioni e si avrà una chiara visione del perchè si è presa quella direzione.

Si sa come appare un programma procedurale: definizioni di dati e chiamate a funzioni. Per cercare il significato di tale programma si deve lavorare un pò, guardando tra chiamate a funzioni e concetti a basso livello per creare un modello nella propria mente. Questa è la ragione per cui abbiamo bisogno di una rappresentazione intermedia quando si progettano programmi procedurali. Di per se, questi programmi tendono a confondere perchè i

termini delle espressioni sono orientati più verso il computer che verso il problema che si sta risolvendo.

Poiche il C++ aggiunge molti concetti nuovi al linguaggio C, l'assunzione naturale può essere che il main() in un programma C++ sarà molto più complicato di un equivalente programma C. Qui si rimarrà piacevolmente sorpresi: un programma C++ ben scritto è generalmente molto più semplice e più facile da capire di un equivalente programma C. Ciò che si vedrà sono le definizioni degli oggetti che rappresentano i concetti nel nostro spazio del problema ( invece che concetti relativi ad aspetti del computer) e i messaggi mandati a quegli oggetti per rappresentare le attività in quello spazio. Una delle delizie della

programmazione orientata agli oggetti è che, con un programma ben progettato, è facile capire il codice leggendolo. Di solito c'è molto meno codice, poichè molti dei problemi saranno risolti riutilizzando il codice delle librerie esistenti.

[4] Si veda Multiparadigm Programming in Leda di Timothy Budd (Addison-Wesley 1995).

[5] Si può trovare un'implementazione interessante di questo problema nel Volume 2 di questo libro, disponibile su www.BruceEckel.com.

[6] qualcuno fa distinzione, indicando che tipo determina l'interfaccia mentre classe è una particolare implementazione di quella interfaccia.

[7] Sono in debito con il mio amico Scott Meyers per questo termine.

[8] Di solito la maggior parte dei diagrammi ha già abbastanza dettagli, quindi non si avrà bisogno di specificare se si utilizza l’aggregazione o la composizione.

[9] Un eccellente esempio di ciò è UML Distilled, by Martin Fowler (Addison-Wesley 2000), che riduce il processo UML, spesso opprimente, ad un maneggevole sottoinsieme.

[10] La mia regola del pollice per stimare tali progetti è: se c'è più di un fattore jolly, non provo neache a cercare di pianificare quanto tempo ci vorrà o quanto costerà fino a che non si ha un prototipo funzionante. Ci sono troppi gradi di libertà.

[11] Grazie per l'aiuto di James H Jarrett.

[12] Maggiori informazioni sugli use case possono essere trovate in Applying Use Cases di Schneider & Winters Wesley 1998) e Use Case Driven Object Modeling with UML di Rosenberg (Addison-Wesley 1999).

[13] La mia personale opinione su ciò è cambiata in seguito. Duplicare ed aggiungere il 10 percento darà una accurata stima ( assumento che non ci sono molti fattori jolly), ma si deve lavorare ancora abbastanza diligentemente per finire in quel tempo. Se si vuole tempo per renderlo elegante ed apprezzarsi del processo, il corretto moltipicatore è tre o quattro, io credo.

[14] Per chi inizia, raccomando il predetto UML Distilled.

[15] Python (www.Python.org) viene spesso usato come un "pseudo codice eseguibile ".

[16] Almeno un aspetto dell'evoluzione è discusso nel libro di Martin Fowler Refactoring: improving the design of existing code (Addison-Wesley 1999). Questi libro utilizza esclusivamente esempi in Java. [17] Questo termine è esplorato nel capitolo Design Patterns del Volume 2.

[18] Ciò è tipo la "prototipazione rapida" dove si suppone di costruire una versione rapida e sporca in modo da imparare qualcosa del sistema e poi gettare via il prototipo e costruirlo esatto. Il problema della

prototipazione rapida è che la gente non getta via il prototipo, ma ci costruisce sopra. Combinata con la mancanza di struttura della programmazione procedurale, ciò spesso produce sistemi disordinati che sono costosi da manuntenere.

[19] Sebbene ciò possa essere una prospettiva più Americana, le storie di Hollywood arrivano ovunque. [20] Incluso (specialemente) il sistema PA. Una volta ho lavorato in una azienda che insisteva nel diffondere ogni telefonata che arrivava ad ogni executive ed essa interrompeva costantemente la nostra produttività ( ma i manager non concepivano di soffocare una cosa così importante come il PA). Alla fine, quando nessuno guardava ho cominciato a tagliare i cavi delle casse.

[21] Dico posso perchè, a causa della complessità del C++, potrebbe convenire passare a Java. Ma la decisione di quale linguaggio scegliere ha molti fattori e si assume che si è scelto il C++.

[22] Tuttavia, si vedano gli articoli di Dan Saks nel C/C++ User's Journal per importanti inestigazioni sulle performance della libreria C++ .

[23]A causa di miglioramenti della produttività, Java dovrebbe essere preso in considerazione a questo punto.

Nel documento Pensare in C++, seconda ed. Volume 1 (pagine 44-49)

Documenti correlati