Nella maggior parte delle discipline ingegneristiche, i sistemi si progettano a partire da componenti che sono usati anche da altri sistemi.
L’Ingegneria del Software si è originariamente preoccupata soprattutto dello sviluppo di software ex-novo, ma oggi è ben noto che occorre adottare processi di sviluppo basati su un riuso sistematico del software:
Riusare software esistente può consentire di:
Riusare è possibile a diversi livelli:
Maggiore affidabilità
Il software riusato è, generalmente, più affidabile (in quanto già provato e testato) di quello prodotto ex-novo.
Minori rischi di progetto
Se si può riusare software, piuttosto che svilupparlo ex-novo, si possono fare stime più accurate sui costi del progetto.
Sviluppo più rapido
I tempi di sviluppo si accorciano ed è possibile consegnare il software più rapidamente.
Maggiori costi di manutenzione
Se si riusa software di cui non si possiede il codice, il sistema complessivo potrà risultare meno flessibile e meno manutenibile.
Mancanza di strumenti CASE
Spesso i CASE non forniscono funzionalità che consentono un efficace riuso di librerie di componenti software.
Diffidenza verso software prodotto da altri
Spesso si preferisce risviluppare per avere un maggior controllo sul software prodotto.
Difficoltà nel creare e Mantenere librerie di componenti riusabili;
Popolare librerie di componenti riusabili può essere costoso, e le tecniche disponibili per classificare, catalogare e ricercare componenti software non sono ancora mature.
Difficoltà nel trovare, comprendere ed adattare componenti riusabili;
Non sempre si è disposti a spendere tempo per cercare, comprendere ed eventualmente adattare un componente riusabile.
Il Riuso di componenti già implementati obbliga ad ereditare le scelte di progetto e di sviluppo di chi ha realizzato I componenti, limitando le situazione nelle quali il riuso è possibile…
Ad un maggiore livello di astrazione, è possibile invece riutilizzare “concetti”, ovvero scelte effettuate durante la specifica dei requisiti o la fase di progettazione;
Scopo dei pattern
Cosa fornisce un design pattern al progettista software?
Definizione:
ogni pattern descrive un problema specifico che ricorre più volte e descrive il nucleo della soluzione a quel problema, in modo da poter utilizzare tale soluzione un milione di volte, senza mai farlo allo stesso modo.
Abbastanza astratti in modo da poter essere condivisi da progettisti con punti di vista diversi.
Non complessi nè domain-specific non rivolti alla specifica applicazione ma riusabili in parti di applicazioni diverse.
Un Design Pattern Nomina, Astrae, e Identifica gli aspetti chiave di una struttura comune di design che la rendono utile nel contesto del riuso in ambito object-oriented.
Un Design Pattern identifica
Un pattern è formato da quattro elementi essenziali:
Un generatore è un software che è in grado di generare, a sua volta, software parametrizzato in base a delle specifiche fornite dall’utente.
I generatori possono essere utilizzati nell’ambito di quei problemi per i quali esistono soluzioni ben consolidate che però dipendono notevolmente dai dati in ingresso.
I dati in ingresso al generatore di programmi vanno a descrivere la conoscenza relativa al dominio per il quale debba essere utilizzato il programma da generare.
Generatori di applicazioni per gestione dati aziendali;
I dati di dominio servono semplicemente alla personalizzazione del prodotto.
Parser e analizzatori lessicali per analisi di codice:
Generatori di codice basati su modelli
Il riuso basato su generatori riduce notevolmente il costo di sviluppo e produce codice molto affidabile.
Tramite generatori di codice si possono ottenere programmi più versatili e performanti di quanto si possa ottenere limitandosi a leggere direttamente dal database, a tempo di esecuzione, i dati relativi alla personalizzazione;
Non tutti i generatori di codice, però, sono in grado di generare codice che sia anche efficiente.
Scrivere una descrizione di dominio per un utente programmatore è più semplice che sviluppare programmi da zero (anche se lo skill richiesto non è minimo).
La loro applicabilità si limita a poche tipologie di problemi.
Spesso il linguaggio col quale descrivere il problema al generatore ha una semantica molto limitata.
Famiglia di standard di modellazione (basata su UML e standardizzata da OMG), pensati allo scopo di generare codice eseguibile a partire da modelli.
I framework rappresentano modelli astratti di progetto di sotto-sistemi. Le applicazioni si costruiscono integrando e completando una serie di framework.
Si differenziano dai design patterns per il fatto di essere astrazioni di livello più alto, a livello architetturale anzichè di design.
Infrastruttura di sistema
Supportano lo sviluppo di infrastrutture come comunicazioni, interfacce utente, e compilatori.
Integrazione di middleware
Composti da standard e classi di oggetti per la comunicazione e lo scambio di informazioni tra oggetti (es. CORBA, COM+, Enterprise Java Beans).
Applicazioni aziendali
Integrano la conoscenza per specifici domini di applicazione (es. telecomunicazioni o sistemi finanziari) e supportano lo sviluppo di nuove applicazioni.
I primi due tipi rientrano anche nella categoria dei Framework Orizzontali mentre le Applicazioni aziendali si considerano come Framework Verticali.
Spesso i framework sono istanziazioni di una serie di design pattern.
L’utilizzo di un framework da parte di programmatori e progettisti comporta il raggiungimento di un notevole skill riguardante la conoscenza della struttura del framework e delle opportunità da esso messe a disposizione.
Spesso è necessario molto tempo, prima di poter maturare tali conoscenze.
É un framework usato per la progettazione di GUI.
Permette presentazioni diverse di uno stesso oggetto e fornisce interazioni separate con queste presentazioni.
MVC richiede l’istanziazione di vari design pattern (es. Observer, Strategy, Composite, …).
Consiste nel riutilizzare, eventualmente previa riconfigurazione o personalizzazione, intere applicazioni.
Le applicazioni possono essere riutilizzate direttamente o essere integrate fra loro come componenti indipendenti all’interno di più ampi sistemi.
Esistono due approcci principali:
È sicuramente possibile il riutilizzo di applicazioni che siano senza stato (quindi si limitino a fornire una risposta a seguito di una richiesta).
Ad esempio la filosofia UNIX prevede la costruzione di un gran numero di piccole applicazioni versatili (ad esempio grep
) che possano essere composte e ricombinate allo scopo di ottenere applicazioni complesse.
Altro esempio: Web Services.
COTS – Commercial Off-The-Shelf- Software commerciale che può essere usato dai suoi acquirenti senza modifiche (es. Soluzioni desktop, prodotti server…).
Esempio storico di COTS sono i DBMS.
Si tratta di applicazioni complete che spesso offrono un API (Application Programming Interface) per permettere ad altri componenti software di accedere alle proprie funzionalità.
Nella pratica, i COTS sono composti di un insieme di classi astratte di interfaccia visibili all’esterno e di un insieme di classi astratte e concrete non visibili.
Costruire grandi sistemi integrando COTS è una strategia abbastanza efficiente per sistemi le cui funzionalità base siano abbastanza comuni;
Ad esempio per realizzare sistemi di E-Commerce, potrebbero essere riutilizzabili COTS che implementano soluzioni ai problemi di autenticazione, gestione del database, invio delle e-mail, browsing delle pagine web, etc.
Tramite COTS si velocizza il processo di sviluppo riducendo i costi di sviluppo e test.
Quali COTS offrono le funzionalità più appropriate?
Possono esserci diversi prodotti COTS utilizzabili tra cui scegliere in base a fattori come costo, completezza, affidabilità.
Come avviene lo scambio dei dati?
L’utilizzo di COTS comporta sempre lo sviluppo di codice per la conversione dei dati verso il formato richiesto dall’applicazione o l’eventuale adattamento dell’applicazione a tali strutture dati.
Quali caratteristiche del prodotto COTS vengono utilizzate?
La maggior parte dei prodotti COTS espongono una grande quantità di funzionalità, molte più di quante necessarie.
È opportuno negare l’accesso alle funzionalità non utilizzate.
Può essere conveniente economicamente scegliere l’adozione di COTS più ridotti.
Una organizzazione vuole dotarsi di un sistema per consentire ai suoi dipendenti di effettuare ordini dai propri PC.
L’organizzazione possiede già un sistema COTS per l’ordinazione ed uno per la fatturazione e consegna (usato solo dall’ufficio ordini). Si sceglie di costruire il nuovo sistema integrando tali COTS.
Sul lato client, saranno usati programmi standard di e-mail e web browsing.
Sul server, si integrerà una piattaforma per l’e-commerce con I due sistemi esistenti.
Saranno necessari degli adattatori per consentire lo scambio di dati.
Verrà inoltre usato un sistema di e-mail per generare e-mail di notifica e ci sarà bisogno di un altro adattore per ricevere dati dal sistema di fatturazione.
Per poter dialogare con applicazioni/componenti esistenti è necessario
Possibili soluzioni al problema della realizzazione degli adattatori:
Mancanza di controllo sulle funzionalità e sulle prestazioni
Il sistema è utilizzato a scatola chiusa: non siamo consapevoli di come avvengano realmente le operazioni nel suo interno e, di conseguenza, non siamo in grado di modulare le richieste in modo da ottimizzare le prestazioni.
Problemi di interoperabilità tra sistemi COTS
Può essere necessario dover scrivere del codice extra per integrare sistemi COTS di produttori indipendenti.
Nessun controllo sull’evoluzione del sistema
Può avvenire che le nuove versioni del sistema rendano impossibile l’interazione col nostro software costringendoci a rimanere legati alle vecchie versioni, per le quali non c’è più manutenzione.
Supporto dei produttori COTS
Tipicamente il supporto dei produttori potrebbe terminare con l’acquisto del prodotto o limitarsi alle sole evoluzioni decise dal produttore.
Per linee di prodotti software si intendono famiglie di applicazioni con funzionalità generiche che si prestano ad essere configurate o adattate in modo da poter essere utilizzate in contesti specifici.
Esempi di adattamento:
Specializzazione della piattaforma
Possono essere necessarie diverse versioni per diversi sistemi operativi o hardware, senza modificare le funzionalità.
Specializzazione dell’ambiente
Possono essere necessarie diverse versioni per venire incontro alle diverse funzionalità e modalità di funzionamento dei dispositivi periferici del sistema.
Specializzazione funzionale
Possono essere necessarie diverse versioni personalizzate in base alle esigenze dei diversi clienti cui sono destinate.
Specializzazione di processo
Possono essere necessarie diverse versioni per supportare I diversi processi di business da eseguire.
Può avvenire in due momenti diversi:
Enterprise Resource Planning (ERP): sistema (generico) che supporta comuni processi aziendali (quali gestione ordini, fatture, inventari, paghe) (es. SAP e BEA).
Il processo di configurazione degli ERP si basa sull’adattamento di un core generico attraverso l’inclusione e la configurazione di moduli, e incorporando conoscenza su processi e regole aziendali del cliente specifico in un database di sistema.
Molto usati in grandi aziende, costituiscono la forma di riuso più comune.
Per mantenere adattabilità e riconfigurabilità è utile adottare architetture modulari e stratificate, che permettano facilmente le necessarie modifiche.
Architettura tipica: multilayer
Inoltre, è importante separare le funzionalità generiche dai dati che si riferiscono alla personalizzazione, in modo da poter realizzare tale customizzazione senza generazione di codice.
2. Ciclo di Vita e Processi Software
3. Processi per lo sviluppo rapido del software
4. Sviluppo Agile del Software
5. Test Driven Development (TDD)
7. Component Based Software Engineering (CBSE): Generalità
8. Component Based Software Engineering (CBSE): Il processo di svi...
9. Ingegneria del Software orientato ai Servizi
10. Ingegnerizzazione dei Servizi
11. I Processi di Manutenzione del Software
12. Reengineering, Refactoring e Reverse Engineering del Software
13. Verifica e Convalida del Software. Richiami e concetti di base ...
14. Tecniche di Testing Dinamico
15. Testing di Sistemi Object Oriented
16. Automazione del testing e Analisi Mutazionale
17. Tecniche di Analisi Statica del codice e il Debugging
18. Stima dei costi nei progetti Software
19. Il Modello COCOMO per la stima dei costi Software – La gestio...
20. Gestione e Miglioramento dei Processi di Produzione del Softwar...
21. La Valutazione della Qualità dei Processi Software – Il Capa...
I.Sommerville, Ingegneria del Software, 8° edizione - Cap. 18 (Riuso)