Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Anna Rita Fasolino » 12.Reengineering, Refactoring e Reverse Engineering del Software


Gli interventi per ‘Ringiovanire’ il software

Sono finalizzati a migliorare la manutenibilità di un software ormai deteriorato dagli interventi di manutenzione subiti.
Diverse tipi di intervento possibili:

  • Ridocumentazione
  • Restructuring (o Refactoring)
  • Reengineering
  • Reverse Engineering

Ridocumentazione

Consiste in una analisi statica del codice sorgente (attraverso appositi strumenti) al fine di produrre documentazione del sistema.

Si analizzano: usi delle variabili, chiamate fra componenti, path del flusso di controllo, dimensioni dei componenti, parametri di chiamate, per capire cosa fa il codice e come lo fa.

Gli output di una attività di ridocumentazione possono essere:

  • grafi delle chiamate,tabelle delle interfacce delle funzioni, dizionari dati, diagrammi del data-flow o control-flow, pseudo-codice, cross-reference fra componenti o variabili.
  • Tali output si possono usare per verificare se il software ha bisogno di ristrutturazione.

Restructuring

Attività che trasforma il codice esistente in codice equivalente dal punto di vista funzionale, ma migliorato dal punto di vista della sua qualità.
In genere si esegue in tre passi:

  1. Analisi statica del codice per ottenerne una rappresentazione interna (es. call graph, control-flow graph…)
  2. Semplificazione della rappresentazione interna attraverso tecniche di trasformazione automatiche.
  3. La nuova rappresentazione viene usata per generare una versione strutturata (migliorata) ed equivalente al codice originario.

Refactoring

Anche i sistemi object-oriented sono soggetti al deteriorarmento e diventano legacy!
Il refactoring è un insieme di tecniche usabili per migliorare il codice ed il design di sistemi object-oriented.
Martin Fowler è autore del libro “Refactoring: Improving the Design of Existing Code” (1999) dove presenta più di 70 pattern per eseguire il refactoring.
Tali tecniche cercano di eliminare i cosiddetti Bad Smells dal codice.

Refactoring (segue)

  • “Refactoring is the art of improving the design of existing code. Refactoring provides us with ways to recognize problematic code and gives us recipes for improving it.” [William C. Wake]
  • “A change to the system that leaves its behavior unchanged, but enhances some non-functional quality – simplicity, flexibility, understandability, …” [Kent Beck]
  • “The process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure” [Fowler]

Esempi di Bad Smells nel codice


Esempi di Tool per il Refactoring


Reengineering

It is the examination and alteration of a subject system to reconstitute it in a new form and the subsequent implementation of the new form [Chikofsky & Cross][1 ]

La reingegnerizzazione (reengineering) è un’attività di re-implementazione di un sistema software esistente svolta per migliorarne la manutenibilità.

Essa può comprendere: ridocumentazione, ristrutturazione e riscrittura di parte del software (o anche di tutto) senza modificare l’insieme di funzionalità che esso realizza.

[1] Chikofsky and Cross, Reverse engineering and design recovery: A taxonomy. IEEE Software, 1990.

Obiettivi del Reengineering

  • Modularizzazione del sistema: suddivisione di un sistema monolitico in parti da riusare separatamente;
  • Miglioramento delle Performance: migliorare le prestazioni di un sistema esistente;
  • Migrazione (o Porting) verso altre Piattaforme:
    • conversione del sistema per renderlo operativo in una diversa piattaforma (hardware o software);
    • richiede di localizzare I componenti dipendenti dalla piattaforma;
  • Estrazione del progetto: per migliorare maintainability, portability, etc;
  • Usare una nuova Tecnologia: quali nuove caratteristiche di un linguaggio, standards, librerie, etc.

Tecniche per il Reengineering

Restructuring

  • Conversione automatica di un codice non strutturato in un codice strutturato
  • Traduzione del codice sorgente

— [Chikofsky and Cross][1]
Reengineering dei dati

  • Integrazione e centralizzazione di diversi database
  • Unificazione di rappresentazioni multiple e ridondanti dei dati
  • Aggiornamento del modello dei dati

— [Sommerville]
Refactoring

  • Rinominare/spostare metodi, classi.. etc.

Reverse Engineering

  • Analisi del codice ed estrazione di informazioni relative alla sua struttura e funzionalità

[1] Chikofsky and Cross, Reverse engineering and design recovery: A taxonomy. IEEE Software,1990

Il ciclo di vita del Reengineering

Fig. 1: Il processo di esecuzione di un intervento di Reengineering.

Fig. 1: Il processo di esecuzione di un intervento di Reengineering.


Reengineering vs. Restructuring

Reengineering

  • Attività di ristrutturazione a livello della riorganizzazione dell’architettura modulare di un sistema; si parte da una certa organizzazione dei moduli del sistema e del relativo flusso dati, e se ne producono altre con migliori caratteristiche di qualità.
  • Esempi: attività per la riduzione dell’accoppiamento fra i moduli, per il controllo dell’uso di variabili globali e la riorganizzazione di data repository …

Restructuring (o Code Refactoring)

  • Attività che trasforma il codice esistente in codice equivalente dal punto di vista funzionale, ma migliorato dal punto di vista della sua qualità.

Forward engineering e reengineering


Reverse Engineering

È un’attività che consente di ottenere specifiche e informazioni sul design di un sistema a partire dal suo codice, attraverso processi di estrazione ed astrazione di informazioni.

La definizione di Chikofsky and Cross, 1990 [1]:
Analyzing a subject system

  • to identify the system’s components and their inter-relationships and
  • to create representations of the system in another form or at a higher level of abstraction

A two-steps process

  • information extraction
  • view abstraction

[1] Chikofsky and Cross, Reverse engineering and design recovery: A taxonomy. IEEE Software, 1990.

Che cosa è il reverse engineering

A partire dal software e dalla sua documentazione, si ricostruiscono
nuove viste descrittive del software, usando idonei analizzatori e visualizzatori.

A partire dal software e dalla sua documentazione, si ricostruiscono nuove viste descrittive del software, usando idonei analizzatori e visualizzatori.


Fasi di Estrazione ed Astrazione

I processi di Reverse Engineering si basano su due fasi fondamentali:
Estrazione

  • Analisi del codice o di altri artifatti software, allo scopo di ottenere informazioni relative al sistema analizzato.
  • Particolarmente utili sono quelli strumenti in grado di estrarre informazioni da un codice sorgente qualsiasi, nota che sia la grammatica del linguaggio di programmazione (ad esempio JavaCC).

Astrazione

  • Si esaminano le informazioni estratte e si cercano di astrarre diagrammi, o viste, ad un più alto livello di astrazione (es.: diagrammi di progetto, architetturali, del dominio dei dati).
  • I processi di astrazione non sono completamente automatizzabili poichè necessitano di conoscenza ed esperienza umana.

Un Modello concettuale per il Reverse Engineering (RE)

Canfora e Di Penta [1] hanno recentemente proposto un modello concettuale che sistematizza tutti i concetti chiave di un processo di reverse engineering, quali:

  • Goal del processo
  • Artifatti coinvolti nel RE
  • Analizzatori usabili
  • Viste producibili

[1] Canfora, Di Penta “Frontiers of Reverse Engineering: a Conceptual Model”, FOSM08 – IEEE Comp. Soc. 2008.

Un Modello Concettuale per il RE

I componenti fondamentali del modello concettuale:

  • Core model: descrive il processo di reverse engineering, obiettivi del reverse engineering, concetti di base.
  • Artifatti: I vari oggetti coinvolti nei compiti di reverse engineering.
  • Analizzatori: strumenti/ attività che analizzano gli artifatti software per popolare una base di conoscenza.
  • Views: rappresentazioni di più alto livello del software, ottenute interrogando la base di conoscenza.

Obiettivi del Reverse Engineering

I processi di Reverse engineering vengono svolti per raggiungere i seguenti obiettivi:

  • Obiettivi di Cambiamento: generare un prodotto rinnovato mediante interventi di migrazione, modernizzazione, modularizzazione.
  • Obiettivi di comprensione: aumentare la conoscenza posseduta su un determinato prodotto software
    • Produrre viste di alto livello usando un apposito Astrattore;
    • Si può partire dal codice sorgente (se disponibile), ma anche dal codice binario;
    • Esempi di possibili scopi: ricostruire un modello dell’architettura software, modelli di progetto, relazioni di tracciabilità, viste metriche sul software.

Modalità di esecuzione del Reverse Engineering

I processi di Reverse engineering sono spesso eseguiti in maniera (semi) automatica.

L’intervento manuale degli ingegneri del software è fondamentale e non eliminabile.

  • Hanno il compito di valutare le viste prodotte automaticamente attraverso il processo di reverse.
  • Forniscono feedback relativi alle analisi automatiche che permettono di ottenere migliori e più accurate viste sul software.

Gli analizzatori per i processi di Reverse Engineering

Esistono diverse categorie di analizzatori usabili per il RE:

  • Analizzatori Statici (analisi di codice sorgente o di binario).
  • Analizzatori Dinamici (analisi di tracce di esecuzione).
  • Analizzatori di serie di dati storici.
  • Analizzatori Ibridi (combinano varie forme di analisi).

Analisi Statica

Il codice sorgente o altri artifatti software possono essere analizzati per ricostruire un modello di rappresentazione del codice (ad esempio un ‘Parse Tree’).
Si possono usare grammatiche di tipo ‘Island grammars’ o trasformazioni di codice

  • Vantaggi: è una analisi abbastanza veloce, economica, e completa.
  • Svantaggi: non è in grado di ricostruire correttamente modelli di descrizione del comportamento / modelli dinamici del software quali: State machines , Sequence diagrams, Pattern di comportamento.
  • Difficoltà con sistemi riconfigurabili a run-time che fanno uso di: Puntatori, Polimorfismo, Ultra-late binding.

Un esempio di Analisi Statica


Analisi Dinamica

Il sistema viene esercitato mediante casi di test, oppure impiegando i dati tratti da scenari d’uso realistici.
Si basa sulla raccolta di tracce di esecuzione.
Può essere necessaria l’instrumentazione del codice per raccogliere tali tracce.

Vantaggi:

  • E’ in grado di risolvere i problemi di analisi di codice riconfigurato dinamicamente
  • Consente di ricostruire modelli dinamici del comportamento del software

Problemi:

  • Il codice deve essere compilabile
  • La qualità dei modelli ricostruiti dipende molto dai dati di input usati durante l’esecuzione
  • I modelli potrebbero pertanto essere incompleti
  • L’analisi può essere molto costosa

Esempio di Analisi Dinamica


Analizzatori di dati storici

É possibile usare altre informazioni sul software analizzato quali:

  • Come cambia un artifatto durante la sua vita?
  • Quando è stato cambiato?
  • Perchè è stato cambiato? Aggiunta di requisiti, correzione di bug,refactoring, re-documentation…
  • Chi lo ha cambiato?
  • Quali artifatti sono cambiati insieme?

Tali informazioni consentono di identificare le parti più soggette a cambiamenti, più difettose o vulnerabili, che tendono a cambiare insieme.

Artifatti analizzabili

Quali artifatti software possono essere analizzati durante un processo di reverse engineering?

  • L’analisi statica si concentra su: requisiti, modelli di progetto, codice sorgente, dati, file di configurazione o di build,qualunque file di documentazione testuale, etc.
  • I file binari possono essere sottoposti a decompilazione.
  • L’analisi dinamica analizza tracce di esecuzione.
  • L’analisi storica: per ciascun artifatto è possibile ottenere la storia delle sue revisioni attraverso sistemi di gestione delle versioni quali CVS/SVN.

Qualora un artifatto necessario per un task di comprensione o di cambiamento non sia disponibile, esso può essere ricostruito mediante reverse engineering!

Viste Software

Sono ottenute a partire dalle informazioni prodotte dagli analizzatori usando meccanismi di interrogazione.

Esempi di meccanismi di interrogazione:

  • Uso di linguaggi di Turing completi, come quello usato dal software Refinery toolkit;
  • Uso di linguaggi per la programmazione logica (e.g. Prolog);
  • GuPRO: linguaggi dichiarativi per interrogare strutture a grafo;
  • XQuery: quando le informazioni estratte sono codificate in XML.

Le viste ottenute sono a loro volta costituite da artifatti e relazioni fra artifatti.

Differenti tipi di viste: esempi

Vista Architetturale. Prodotta dal tool RIGI [1]

Vista Architetturale. Prodotta dal tool RIGI [1]

Vista Polimetrica. Prodotta dal tool CodeCrawler [2]

Vista Polimetrica. Prodotta dal tool CodeCrawler [2]


Differenti tipi di viste: esempi (segue)

Code View. Example: CodeSurfer [3]

Code View. Example: CodeSurfer [3]

Vista Storica. Esempio: Evolution Storyboards [4]

Vista Storica. Esempio: Evolution Storyboards [4]


Conclusioni

Esistono diverse strategie di manutenzione alternative a cui un sistema software può essere sottoposto.
Come scegliere tra le varie opzioni?

Necessità di idonei modelli decisionali che guidino la scelta sulla base del Valore Tecnico e del Valore di Business di un sistema.
Un esempio di approccio decisionale è descritto in [1]

[1] De Lucia, A., Fasolino, A.R., Pompella, E., 2001. A decisional framework for legacy system management. In Proceedings of the IEEE International Conference on Software Maintenance, IEEE CS Press, pp. 642 – 651.

Nove cose da poter fare con software legacy

Una recente analisi di strategie proposta da Grady Booch

1. Abbandonarlo
Quando il suo valore economico si è esaurito, o lo sforzo di risviluppo non è eccessivo.

2. Regalarlo
Se non serve più, si può cederlo a qualche comunità open-source dove potrà ancora tornare utile a qualcuno.

3. Ignorarlo
Se è abbastanza stabile, e fa qualcosa di utile, si può continuare a usarlo senza però modificarlo.

G. Booch, Nine things you can do with old software, IEEE Software, Sept 2008.

Nove cose da poter fare con software legacy (segue)

4. Farlo sopravvivere
Quando l’hardware su cui gira non è più supportato (e non si dispone del codice sorgente per portarlo in nuove piattaforme), si fa sopravvivere o cercando vecchio hardware da cannibalizzare, o usando emulatori di piattaforma.
5. Riscriverlo
Quando la manutenzione è troppo costosa, o il sistema è troppo fragile, si può riscriverlo (ma sapendo che ottenere un sistema funzionalmente equivalente al primo è impossibile, e che bisognerà probabilmente convincere gli utenti ad accettare qualche cambiamento).
6. Farlo fruttare (in qualche modo)
Cercare parti del sistema da conservare (algoritmi, pattern, astrazioni…) perché ancora utili, ed usarle come una base di conoscenza per un nuovo sviluppo.

Nove cose da poter fare con software legacy (segue)

7. Wrapping
Usare tecniche di wrapping per integrarlo in nuove piattaforme (quali SOA).
8. Trasformarlo
È la strategia più difficile e va praticata per mantenere il sistema in condizioni ottimali, se si prevede di continuare ad usarlo a lungo termine: va dal semplice refactoring, alla trasformazione architetturale.
9. Preservarlo
Anche il software antico può avere un valore storico (es. vecchi sistemi operativi, o videogiochi) e culturale da preservare (magari in un Museo della Storia dei Computer).

Conclusione di Booch

Per Software economicamente interessante ci sono due possibili opzioni di gestione:

Preservarlo

  • Si fa per motivi soprattutto irrazionali (avversione al rischio)

Farlo evolvere

  • Quando ciò può contribuire al suo valore a lungo termine

La scelta è alla fine sempre dettata da fattori economici (e non solo tecnici)!

I materiali di supporto della lezione

Sommerville, Ingegneria del Software, 8a ed., Capitolo 21

Ulteriori Letture Raccomandate

Canfora, Di Penta “Frontiers of Reverse Engineering: a Conceptual Model”, FOSM08 – IEEE Comp. Soc. 2008

Grady Booch, Nine Things you can do with old software, IEEE Software, Sept/Oct 2008

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion