Professional Documents
Culture Documents
Introduzione
Argomenti
Evoluzione dello sviluppo del software Prodotto software Processo di sviluppo del software
Attivit Modelli Prototipi Linguaggi di modellazione UML
Fattori di qualit
Ingegneria del Software T 1.2
1.4
1.5
Problema
produttivit produttivit complessit complessit enorme aumento della complessit
Rivoluzione software
Assembler linguaggi di alto livello (Fortran, Cobol, Algol) programmazione strutturata (Pascal, C) programmazione modulare ADT (Ada, Modula-2) programmazione orientata agli oggetti (Smalltalk, C++, Eiffel, CLOS, Object Pascal, Java, C#, )
1.6
1990
1.7
Nel 1968, durante una conferenza sull'evoluzione del software, viene coniato il termine ingegneria del software
1.8
Prodotto Software
Codice che, quando eseguito, svolge una funzione prestabilita con prestazioni prestabilite Strutture dati mediante le quali il codice tratta adeguatamente le informazioni Documenti che descrivono le operazioni e luso del prodotto software:
documentazione tecnica manualistica di installazione manualistica di utilizzo
1.10
Prodotto Software
Pu essere realizzato
per un particolare cliente per il mercato in generale
1.11
Prodotto Software
Si sviluppa, non si fabbrica
Cliente Sviluppatore/i Processo di sviluppo Linguaggio e strumenti di modellazione
1.12
Il successo di un progetto
Non pu essere garantito determinato
Principalmente da fattori umani Solo secondariamente da scelte tecnologiche
1.13
1.14
Buoni sviluppatori possono fornire una soluzione, ma ottimi sviluppatori possono fornire
soluzioni migliori pi velocemente a minor costo
1.15
1.16
Ingegneria tradizionale
Il problema dello sviluppo del software un problema di gestione della complessit In altri settori, l'uomo ha imparato bene a progettare e costruire sistemi complessi, come un edificio, un'automobile, un calcolatore, un impianto industriale Quali sono i principi usati nell'ingegneria tradizionale per affrontare la complessit?
1.17
Standardizzazione dei componenti in modo che possano essere facilmente collegabili e intercambiabili
1.18
Lo sviluppo di un progetto non lasciato al caso o allestro di pochi progettisti, ma unattivit in larga misura sistematica
1.19
del prodotto
1.20
1.21
Studio di fattibilit Analisi dei requisiti Specifica dei requisiti Progettazione Realizzazione e collaudo dei moduli Integrazione e collaudo del sistema Installazione e training Utilizzo e manutenzione
Ingegneria del Software T 1.22
Studio di fattibilit
Valutazione preliminare dei costi e dei benefici per stabilire se si debba avviare lo sviluppo dellapplicazione
Alternative possibili Scelte pi ragionevoli Risorse finanziarie e umane necessarie per lattuazione del progetto
Il contenuto di questa fase risulta largamente variabile da caso a caso, in funzione del tipo di prodotto e dei ruoli del committente e del produttore dellapplicazione
1.23
Studio di fattibilit
Il risultato della fase di studio di fattibilit un documento che dovrebbe contenere le seguenti informazioni:
definizione preliminare del problema possibili scenari che illustrino eventuali diverse strategie di soluzione costi, tempi e modalit di sviluppo per le diverse alternative
Il committente pu allocare risorse finanziarie perch venga condotto uno studio di fattibilit completo
1.24
1.25
1.26
1.27
1.28
1.29
Progettazione
Si definisce larchitettura generale (hardware e software) del sistema
Si decompone larchitettura software in uno o pi programmi eseguibili Per ogni programma, si descrivono: le funzioni che svolge le relazioni con gli altri programmi Si decompone ogni programma eseguibile in pi moduli Per ogni modulo, si descrivono: le funzioni che svolge le relazioni con gli altri moduli
1.31
Progettazione
Progettazione object-based
Tipi di dati astratti Incapsulamento
Progettazione object-oriented
Ereditariet Polimorfismo
Progettazione
Architettura del sistema
Modello repository Modello client-server Modello abstract-machine
Progettazione
Risultato: documento di specifiche di progetto nel quale la definizione dellarchitettura software pu anche essere data in maniera rigorosa, o addirittura formale, usando opportuni linguaggi di specifica di progetto Stiamo realizzando correttamente il prodotto?
1.34
1.36
Tecnologie e Linguaggi
C / C++ Java C# HTML Hypertext Markup Language DHTML Dynamic HTML CSS Cascading Style Sheets Javascript
1.37
Tecnologie e Linguaggi
XML eXtensible Markup Language DTD Document Type Definition XSD XML Schema Definition XSL eXtensible Stylesheet Language XSLT XSL for Transformations COM, COM++, DCOM, CORBA, EJB .NET, ADO, LinQ, XAML, WPF, WF, WCF DBMS, SQL, ORM
Ingegneria del Software T 1.38
Tecnologie e Linguaggi
C++
DHTML
C#
CSS
Data Base
Java XML
1.39
alfa test - il sistema rilasciato per luso, ma allinterno dellorganizzazione del produttore beta test - si ha un rilascio controllato a pochi e selezionati utenti del prodotto
Ingegneria del Software T 1.40
1.41
Installazione e training
Deployment Il sistema software viene:
consegnato al cliente installato messo in funzione
Training
1.42
Utilizzo e manutenzione
Il sistema viene utilizzato Fase di manutenzione
la fase pi lunga del ciclo di vita di un prodotto software 50-80% dei costi complessivi
1.43
Utilizzo e manutenzione
Manutenzione correttiva
correzione degli errori che non sono stati scoperti nelle fasi precedenti
Manutenzione adattativa
aumento dei servizi forniti dal sistema in seguito alla definizione di nuovi requisiti
Manutenzione perfettiva
miglioramento delle caratteristiche delle unit del sistema
1.44
Utilizzo e manutenzione
Spesso il software non viene progettato per essere modificato facilmente Vengono apportate modifiche direttamente sui programmi, senza modificare
la documentazione di progetto la documentazione di test la specifica dei requisiti ...
1.45
Utilizzo e manutenzione
Re-ingegnerizzazione del software
Ristrutturazione del codice (refactoring) Conversione del linguaggio Reverse engineering
1.46
1.47
Alcune attivit
possono essere svolte con lausilio di strumenti CASE (Computer-Aided Software Engineering)
Ingegneria del Software T 1.48
Strumenti CASE
Mediante strumenti CASE, possono essere svolte:
la scomposizione funzionale la definizione grafica delle entit in gioco (dati, funzioni, associazioni, ) la definizione delle interazioni
1.49
Strumenti CASE
Sistemi avanzati di CASE riescono a costruire programmi completi e funzionanti partendo da questi diagrammi, purch tutte le informazioni siano state fornite correttamente
1.50
Strumenti CASE
Il processo non cos automatizzato come appare in prima battuta Uno strumento CASE non crea del software ma traduce il progetto di un sistema dalla forma grafica alla forma testuale Sviluppare un progetto grafico completo per un programma pu essere impegnativo quanto lo scrivere il programma direttamente!
1.51
Progettazione
Implementazione
Collaudo
Manutenzione
Ingegneria del Software T 1.53
Modello a cascata
Il modello si fonda sul presupposto che introdurre cambiamenti sostanziali nel software in fasi avanzate dello sviluppo ha costi troppo elevati pertanto, ogni fase deve essere svolta in maniera esaustiva prima di passare alla successiva, in modo da non generare retroazioni Le uscite che una fase produce come ingresso per la fase successiva sono i cosiddetti semilavorati del processo di sviluppo:
Documentazione di tipo cartaceo Codice dei singoli moduli Sistema complessivo
1.54
Modello a cascata
Oltre alle fasi, fondamentale definire: Semilavorati
al fine di garantire che ci possa essere unattivit di controllo della qualit dei semilavorati
Date
entro le quali devono essere prodotti i semilavorati al fine di certificare l'avanzamento del processo secondo il piano stabilito
1.55
Modello a cascata
I limiti sono dati dalla sua rigidit in particolare da due assunti di fondo molto discutibili:
Immutabilit dellanalisi gli utenti sono in grado di esprimere esattamente le loro esigenze e di conseguenza in fase di analisi iniziale possibile definire tutte le funzionalit che il software deve realizzare Immutabilit del progetto possibile progettare lintero sistema prima di aver scritto una sola riga di codice
1.56
Modello a cascata
Nella realt:
La visione che gli utenti hanno del sistema evolve man mano che il sistema prende forma e quindi le specifiche cambiano in continuazione Nel campo della progettazione le idee migliori vengono in mente per ultime, quando si comincia a vedere qualcosa di concreto Inoltre problemi di prestazioni costringono spesso a rivedere le scelte di progetto
1.57
Modello a cascata
Evoluzioni successive al modello originale ammettono forme limitate di retroazione a un livello
Analisi
Progettazione
Implementazione
Collaudo
1.58
Modello a cascata
Per evitare problemi, prima di iniziare a lavorare sul sistema vero e proprio meglio realizzare un prototipo in modo da fornire agli utenti una base concreta per meglio definire le specifiche Una volta esaurito il compito, il prototipo viene abbandonato (throw-away prototyping) e si procede a costruire il sistema reale secondo i canoni del modello a cascata Questo approccio risulta per quasi sempre cos dispendioso da annullare i vantaggi economici che il modello a cascata dovrebbe garantire
1.59
Prototipo
Modello approssimato dellapplicazione Obiettivo: essere mostrato al committente o usato da questi al fine di ottenere un'indicazione su quanto il prototipo colga i reali fabbisogni Deve essere sviluppabile
in tempi brevi con costi minimi
Alternativa interessante in tutti i casi in cui lo sviluppo dellapplicazione parta inizialmente con requisiti non perfettamente noti o instabili
1.60
Prototipo
Prototipazione throw-away
Il prototipo che si realizza del tipo usa e getta Obiettivo: comprendere le richieste del cliente e quindi migliorare la definizione dei requisiti del sistema Il prototipo si concentra sulle parti che sono mal comprese con l'obiettivo di contribuire a chiarire i requisiti
1.61
Prototipo
Programmazione esplorativa
Il prototipo si trasforma progressivamente nel prodotto finale Obiettivo: lavorare a stretto contatto con il cliente per
Chiarire completamente i requisiti Giungere a un prodotto finale
Prima, si sviluppano le parti del sistema che sono ben chiare (requisiti ben compresi) Quindi, si aggiungono nuove parti/funzionalit come proposto dal cliente
Ingegneria del Software T 1.62
Modelli evolutivi
Partendo da specifiche molto astratte, si sviluppa un primo prototipo Da sottoporre al committente Da raffinare successivamente
1.63
Modelli evolutivi
Esistono diversi modelli di tipo evolutivo, ma tutti in sostanza propongono un ciclo di sviluppo in cui un prototipo iniziale evolve gradualmente verso il prodotto finito attraverso un certo numero di iterazioni Il vantaggio fondamentale che ad ogni iterazione possibile confrontarsi con gli utenti per quanto riguarda le specifiche e le funzionalit (raffinamento dellanalisi) rivedere le scelte di progetto (raffinamento del design)
Ingegneria del Software T 1.64
Modelli evolutivi
Lefficacia di questi modelli si basa su due requisiti: Uniformit fra le tecniche di analisi, design e programmazione Tecnologie e strumenti di sviluppo predisposti allapproccio incrementale I modelli evolutivi si sono orientati verso cicli sempre pi brevi e iterazioni sempre pi veloci, fino ad arrivare al modello pi radicale che prende il nome di Extreme Programming (XP)
1.65
Modelli evolutivi
Lillustrazione, tratta da un articolo di Kent Beck, mostra levoluzione dal modello a cascata, allextreme programming
1.66
Modelli evolutivi
Problemi
Il processo di sviluppo non visibile (ad es., documentazione non disponibile) Il sistema sviluppato poco strutturato (modifiche frequenti) richiesta una particolare abilit nella programmazione (team ristretto)
Applicabilit
Sistemi di piccole dimensioni Parti di sistemi pi grandi Sistemi che avranno breve durata
1.67
Extreme Programming
Si basa su:
Comunicazione: ci deve essere grande comunicazione sia tra gli sviluppatori, sia tra sviluppatori e clienti Testing: necessario avere pi codice per il test che per il programma vero e proprio - ogni programmatore deve scrivere il programma di test parallelamente se non prima di scrivere il codice effettivo
1.68
Extreme Programming
Si basa su:
Semplicit: il codice deve essere il pi semplice possibile - complicare il codice tentando di prevedere futuri riutilizzi controproducente sia come qualit di codice prodotto, sia come tempo necessario - d'altra parte, il codice semplice e comprensibile il pi riutilizzabile Coraggio: non si deve avere paura di modificare il sistema che deve essere ristrutturato in continuazione, ogni volta che si intravede un possibile miglioramento (refactoring)
Ingegneria del Software T 1.69
1.70
Modelli evolutivi
Alto rischio per mancanza di visibilit Basso rischio per sviluppo di nuove applicazioni Sistemi di dimensioni piccole
1.71
Modelli ibridi
Sistemi composti di sotto-sistemi Per ogni sotto-sistema possibile adottare un diverso modello di sviluppo
Modello evolutivo per sotto-sistemi con specifiche ad alto rischio Modello a cascata per sotto-sistemi con specifiche ben definite
Di norma conviene creare e raffinare prototipi funzionanti del sistema o di sue parti, secondo lapproccio incrementale - iterativo
1.72
Sviluppo incrementale
Sviluppo incrementale si costruisce il sistema sviluppandone sistematicamente e in sequenza parti ben definite una volta costruita una parte, essa non viene pi modificata
di fondamentale importanza essere in grado di specificare perfettamente i requisiti della parte da costruire, prima della sua implementazione
1.73
Sviluppo iterativo
Sviluppo iterativo si effettuano molti passi dellintero ciclo di sviluppo del software, per costruire iterativamente tutto il sistema, aumentandone ogni volta il livello di dettaglio
non funziona bene per progetti significativi non consente di valutare correttamente i rischi relativi alle diverse parti del sistema
1.74
1.75
P1'' 1 P2' 2
P3' 3
P1'' 1 P2' 2
P3'' 3
P1'' 1 P2'' 2
P3'' 3
PD1 1 P2'' 2
P3'' 3
1.76
Sviluppo a componenti
Ricerca classi da Ricerca componenti da riusare riusare
Progettazione OO
Analisi OO
Installazione e utilizzo
Valutazione
1.77
Linguaggi di modellazione
Permettono di descrivere (modellare) un sistema di qualche natura Possono essere grafici o testuali
Se grafici, sono basati su uno o pi tipi di diagrammi, costruiti a partire da simboli grafici con una semantica ben definita
Linguaggi di modellazione
Modelli semantici dei dati
Entit-Relazioni (E-R)
Modelli operazionali
Automi a stati finiti Reti di Petri
Modelli descrittivi
Logica del primo ordine Logica temporale
1.79
Linguaggi di modellazione
Nessun cliente vi ringrazier per avergli fornito diagrammi accurati; quello che vorranno da voi software funzionante Perch usare un linguaggio di modellazione? Dobbiamo risolvere un problema di comunicazione tra i progettisti tra i progettisti e il committente tra i progettisti presenti e i progettisti futuri
1.80
Linguaggi di modellazione
Il linguaggio naturale troppo impreciso Il codice preciso, ma troppo dettagliato La soluzione migliore utilizzare un linguaggio di modellazione
Sufficientemente preciso Flessibile dal punto di vista descrittivo per poter arrivare a un qualunque livello di dettaglio Possibilmente standard
1.81
Linguaggi di modellazione
Esiste ormai una convergenza su un unico linguaggio di modellazione di tipo grafico: UML (Unified Modeling Language) Sviluppato verso la met degli anni '90 da Grady Booch, James Rambaugh, Ivar Jacobson Nel 1999, OMG (Object Management Group) ha definito la versione 1.3 del linguaggio (http://www.omg.org) La versione corrente la 2.1 (http://www.uml.org)
Ingegneria del Software T 1.82
1.83
1.84
Diagrammi comportamentali
Diagramma dei casi duso Diagramma delle attivit Diagramma degli stati Diagramma di sequenza Diagramma di comunicazione (ex di collaborazione) Diagramma dei tempi (UML 2.0) Diagramma di sintesi dellinterazione (UML 2.0)
Ingegneria del Software T 1.85
Fattori di qualit
Qualit esterne percepibili da un osservatore esterno che esamina il processo o il prodotto come se fosse una scatola nera (black-box)
Affidabilit Facilit d'uso Velocit
Fattori di qualit
Qualit interne osservabili esaminando la struttura interna del processo o prodotto, come se questo fosse una scatola trasparente (white-box)
Modularit Leggibilit
Lobiettivo di fornire meccanismi precisi di misura non realisticamente raggiungibile (ad esempio, per laffidabilit)
1.88
Correttezza (correctness)
Data una definizione dei requisiti che il software deve soddisfare, il software si dice corretto se rispetta tali requisiti I requisiti specificati risultano spesso incompleti rispetto ai requisiti reali
1.89
Robustezza (robustness)
Il software si dice robusto se si comporta in maniera accettabile anche in corrispondenza di situazioni anomale e comunque non specificate nei requisiti Nel caso di situazioni anomale, il software non deve causare disastri (perdita di dati o peggio) o termina l'esecuzione in modo pulito o entra in una modalit particolare, in cui non sono pi attive alcune funzionalit (graceful degradation mode)
1.90
Affidabilit (reliability)
Il software si dice affidabile se
le funzionalit offerte corrispondono ai requisiti (il software corretto) in caso di guasto, non produce danni fisici o economici (il software robusto) Affidabilit = Correttezza + Robustezza
1.91
Estendibilit (extendibility)
Facilit con cui il software pu essere modificato per soddisfare nuovi requisiti
La modifica di programmi di piccole dimensioni non un problema serio I sistemi software di dimensioni medie e grandi possono soffrire di fragilit strutturale: modificando un singolo elemento della struttura si rischia di far collassare l'intera struttura
1.92
Estendibilit (extendibility)
Due principi essenziali: Semplicit architetturale
pi l'architettura del sistema semplice pi facile da modificare
Modularit e decentralizzazione
pi il sistema suddiviso in moduli autonomi pi facile che una modifica coinvolga un numero limitato di moduli
1.93
Riusabilit (reusability)
Il software riusabile se pu essere riutilizzato completamente o in parte in nuove applicazioni Permette di non dover reinventare soluzioni a problemi gi affrontati e risolti Influenza tutte le altre caratteristiche dei prodotti software
1.94
Compatibilit (compatibility)
Facilit con cui il prodotto software pu essere combinato con altri prodotti Omogeneit nel progetto Utilizzo di standard:
Nel formato dei dati che devono essere scambiati con altre applicazioni (formato XML) Nell'interfaccia utente
1.95
1.96
Efficienza (efficiency)
Buon utilizzo delle risorse hardware:
Processori (tempo di calcolo) Memoria principale (occupazione di memoria) Memorie secondarie Canali di comunicazione
1.97
Portabilit (portability)
Facilit con cui il prodotto software pu essere trasferito su altre architetture hardware e/o software
1.98
Verificabilit (verifiability)
Facilit con cui il prodotto software pu essere sottoposto a test
1.99
Integrit (integrity)
Protezione sicurezza abilit del sistema software di proteggere i vari componenti (programmi, dati, documenti) da accessi e/o modifiche non autorizzati di natura sia volontaria sia involontaria
1.100
Innocuit (safety)
Abilit del sistema software di non entrare mai in uno stato di pericolosit intollerabile Caso di sistemi che possono essere critici e pericolosi anche per la vita dell'uomo
1.101
1.102
Supportabilit (supportability)
possibile utilizzare strumenti CASE?
1.103
Affidabilit (reliability)
il processo definito in modo tale da evitare che errori nel processo si ripercuotano in errori nel prodotto?
Robustezza (robustness)
il processo in grado di proseguire anche al verificarsi di problemi imprevisti?
1.104
Analisi
Per effettuare correttamente lanalisi, necessario
Comunicare con lutente Ottenere una buona conoscenza dellarea applicativa Determinare in dettaglio i requisiti del sistema
Produce un documento dei requisiti base di partenza della fase successiva del processo di sviluppo del software, cio la progettazione Se non viene svolta in modo accurato, pu avere conseguenze molto serie: i costi per gestire requisiti omessi o errati possono diventare insostenibili
2.2
Analisi
Raccolta dei requisiti Analisi del dominio
Produce un modello che descrive il dominio del problema da affrontare: la porzione del mondo reale, rilevante per il sistema Su cui si devono mantenere informazioni Con cui si deve interagire
Produce un modello che descrive le responsabilit del sistema Che cosa deve fare il sistema per soddisfare il cliente Non come il sistema va realizzato
2.3
2.4
2.5
2.6
Strategia preventiva
Si mette in moto molto prima che inizi il lavoro tecnico Si individuano i rischi potenziali, se ne valutano le probabilit e gli effetti e si stabilisce un ordine di importanza Si predispone un piano che permetta di reagire in modo controllato ed efficace Pi grande un rischio Maggiore sar lattenzione che bisogner dedicargli
2.7
Analisi
2.8
Analisi
Analisi
Metodi utilizzati
Interviste, questionari Studio di documenti che esprimono i requisiti in forma testuale Osservazione passiva o attiva del processo da modellare Studio di sistemi software esistenti Prototipi
2.10
Analisi
2.11
Analisi
2.12
Analisi
Analisi
Analisi
Analisi
2.16
Analisi
Analisi
2.18
Analisi
2.19
Analisi
2.20
2.21
2.22
Negozio
Eroga servizi Incassa il pagamento del servizio mediante Guest Card
Servizio
Ha un costo
Guest Card
Unico mezzo per effettuare i pagamenti
Ingegneria del Software T 2.23
Negozio
Eroga servizi il cui costo in euro Incassa il pagamento del servizio mediante Guest Card in euro
Servizio
Ha un costo in euro
Guest Card
Permette di effettuare i pagamenti in euro
Valuta di riferimento
Unica in tutto il Villaggio Turistico In euro
Ingegneria del Software T 2.24
2.25
2.26
2.27
2.28
Analisi
2.29
Analisi
2.30
Analisi
Linsieme di tutti i casi d'uso costituisce limmagine del sistema verso lesterno
2.31
Analisi
Prepara esame
Effettua esame
Esaminando
Esaminatore
2.32
Analisi
Tutti gli esaminandi interpretano lo stesso ruolo Tutti gli esaminatori interpretano lo stesso ruolo
Esaminatore
2.33
Analisi
Esaminando
1. 2. 3. 4. 5.
Lesaminando entra nel sistema (login) Lesaminando inizia lesame Lesaminando naviga tra le domande e risponde Lesaminando termina l'esame Lesaminando esce dal sistema (logout)
Ingegneria del Software T 2.34
Analisi
2.35
Analisi
2.36
Analisi
e di conseguenza
non solo sar in grado di validare i casi duso ma sar anche incoraggiato a partecipare attivamente alla loro definizione
2.37
Analisi
Ogni scenario
potrebbe essere descritto formalmente mediante un diagramma di sequenza, ma viene descritto mediante il linguaggio naturale, che pi adeguato nella fase di raccolta dei requisiti
2.38
3.
4.
Identificare tutti i possibili utilizzi del sistema Definire un attore per ogni categoria di utenza e per ogni ruolo che lutente gioca e che ha rilevanza per il sistema Per ciascun attore identificare tutti gli obiettivi significativi che gli utenti si pongono e che il sistema dovr supportare Per ciascun obiettivo definire un caso duso
2.39
6.
Definire i casi duso senza eccedere nella complessit e nei dettagli mantenendo sempre lo stesso livello di astrazione: singoli passi in un caso duso dalto livello dastrazione possono essere trattati come obiettivi da casi duso di livello dastrazione pi basso Ricontrollare e validare i casi duso insieme agli utenti e ai committenti
2.40
Analisi
2.41
Analisi
include
Effettua esame
include
Effettua validazione
include
Correggi esame
2.42
Analisi
2.43
Analisi
Amministratore
2.44
Casi duso
2.45
Actors
List the actors that interact and participate in this use case
Pre-conditions
Pre-conditions that need to be satisfied for the use case to perform
Post-conditions
Define the different states in which you expect the system to be in, after the use case executes
Basic Flow
List the primary events that will occur when this use case is executed
Ingegneria del Software T 2.46
Special Requirements
Business rules for the basic and alternative flows should be listed as special requirements in the use case narration These business rules will also be used for writing test cases Both success and failure scenarios should be described here
2.47
Analisi
Approccio funzionale
Si basa sulla stessa forma di astrazione applicata dagli uomini per affrontare la complessit del mondo
Permette di gestire la complessit intrinseca del mondo reale Ignorare gli aspetti che non sono importanti per lo scopo attuale Concentrarsi maggiormente su quelli che lo sono
2.49
Analisi
Approccio Funzionale
Tecnica della Scomposizione Funzionale Strategia
Analisi top-down scegliere i passi ed i sotto-passi di elaborazione previsti per il sistema Astrazione procedurale considerare ogni operazione come
una singola entit, nonostante tale operazione sia effettivamente realizzata da un insieme di operazioni di pi basso livello concentra la sua attenzione sulla modularizzazione delle procedure i moduli devono essere il pi possibile indipendenti specifica le elaborazioni e le interfacce delle procedure
Lanalista
La scomposizione in funzioni molto volatile (a causa del continuo cambiamento dei requisiti funzionali)
Ingegneria del Software T 2.50
Analisi
Analisi
Analisi orientata agli oggetti
Produce un modello dei dati o modello statico
la parte fondamentale dellOOA, su cui si basa tutto il resto descrive le entit del mondo reale rilevanti per il sistema
L'insieme dei due modelli costituisce il punto di partenza della successiva fase di progettazione
2.52
Relazioni tra le classi Per ogni classe Responsabilit Attributi Operazioni fondamentali cio servizi forniti allesterno (interfaccia)
Attivit non strettamente sequenziali, ma reiterate sino alla produzione di un modello coerente
Ingegneria del Software T 2.53
2.54
Analisi
2.55
Analisi
Altre fonti
Altri sistemi che funzionano nello stesso dominio o in domini analoghi Enciclopedie, nomenclature e documenti tecnici che descrivono il dominio
Riutilizzare classi, gerarchie e strutture ottenute da precedenti analisi nello stesso dominio
2.56
Analisi
Scegliere un solo termine significativo se pi parole indicano lo stesso concetto (sinonimi) Il nome della classe deve essere un nome familiare
allutente o allesperto del dominio del problema non allo sviluppatore!
2.57
Analisi
2.58
Analisi
Individuare Modelli e loro elementi specifici, cio oggetti descrittivi e istanze specifiche
Insegnamento Ingegneria del Software T CorsoDiStudio Ingegneria Informatica Facolt Ingegneria
2.59
Analisi
Individuare Eventi o Transazioni che il sistema deve gestire e memorizzare - possono avvenire in un certo istante (ad es., una vendita) o - possono durare un intervallo di tempo (ad es., un affitto)
Appello, EsameScritto, Registrazione, AppelloDiLaurea,
Ingegneria del Software T 2.60
Analisi
2.61
Analisi
Analisi
Analisi
Cercare verbi che rappresentano azioni fatte da un oggetto del sistema Utilizzare le classi gi identificate per il semplice fatto di esistere, devono avere almeno una responsabilit Annotare tutte le informazioni che gli oggetti devono mantenere e gestire
Ingegneria del Software T 2.64
Analisi
2.65
Analisi
Lista di responsabilit
I collaboratori sono le altre classi con le quali la classe in esame deve interagire Si utilizzano schede di cartoncino di 10x15 cm
2.66
Analisi
2.67
Analisi
Dipendenza
Collaborazione (relazione usa) Relazione Istanza Classe
Istanza di classe generica Classe generica (istanza di template template)
Analisi
2.69
Analisi
Fornitore superclasse contenuto classe da cui si dipende (che viene usata) classe metaclasse
2.70
Analisi
Individuazione dellereditariet
La classe B (specializzazione o sottoclasse) in relazione IsA con la classe A (generalizzazione o superclasse) e ne eredita
Relazioni Attributi Operazioni A B
B A
2.71
Analisi
Individuazione dellereditariet
Lereditariet deve rispecchiare una tassonomia effettivamente presente nel dominio del problema
Non usare lereditariet dellimplementazione (siamo ancora in fase di analisi!) Non usare lereditariet solo per riunire caratteristiche comuni ad es., Studente e Dipartimento hanno entrambi un indirizzo, ma non per questo c ereditariet!
La ricerca delle relazioni di ereditariet contribuisce a chiarire il significato delle varie classi e pu portare alla scoperta di nuove classi
2.72
Analisi
Analisi
Analisi
Analisi
2.76
matrimonio marito Societ nome indirizzo Persona 1 lavora-per * nome indirizzo datore-lavoro impiegato codiceFiscale dataNascita sottoposto * 0..1 0..1 moglie dirigente 0..1 dirige
1 Poligono
contiene
Finestra
1 1..* 1
BarraTitolo
1 1 1
Pannello
Bordo
Etichetta
Pulsante Chiusura
2.77
Analisi
Se contenitore e contenuto hanno un legame forte e uno stesso ciclo di vita, si tratta di composizione altrimenti, si tratta di aggregazione
2.78
Analisi
2.79
Analisi
Analisi
Significato
valore singolo da 0 a intervallo insieme di valori e/o intervalli
Esempi
1 * 0..1 1..* 1,3..5,7
2.81
Analisi
2.82
Analisi
* 1..*
* 1..*
1..* *
1..* * Veicolo
CompraVendita -dataAcquisto
2.83
Analisi
1..* * Proprietario
1..* * Veicolo
CompraVendita -dataAcquisto
2.84
Analisi
matrimonio
*
Persona
1
marito
*
Matrimonio data
moglie Un Matrimonio in effetti una classe, con due associazioni con oggetti di tipo Persona (marito e moglie).
2.85
Analisi
Unoperazione della classe A utilizza unistanza della classe B (ma non esiste unassociazione tra le due classi)
void fun3() { B b = new B(); usa b }
2.86
Analisi
Nome Interfaccia
Cliente Fornitore
Ingegneria del Software T 2.87
Analisi
2.88
Analisi
AfferisceA
1 Dipartimento -descrizione
2.89
Analisi
Esempi
cognome dataDiNascita annoDiImmatricolazione
Ingegneria del Software T 2.90
Analisi
Analisi
Unit di misura, precisione Visibilit (opzionale in fase di analisi) Pubblica + Protetta # Privata Attenzione: gli attributi devono essere sempre privati!
Ingegneria del Software T 2.92
Analisi
2.93
Analisi
Analisi
Persona altezza: Integer sesso: {femmina, maschio} et() 0..1 marito matrimonio {self.moglie.sesso = femmina and self.marito.sesso = maschio}
0..1 moglie
2.95
Analisi
Analisi
Ricercatore
Ordinario
Associato
2.97
Analisi
2.98
Analisi
2.99
Analisi
2.100
Analisi
2.101
Analisi
2.102
Analisi
2.103
Analisi
2.104
Analisi
2.105
Analisi
Altre operazioni
Devono essere determinate
servizi offerti agli altri oggetti
Analisi
Distruttore
Accessor
Set - modifica il valore di un attributo atomico oppure collega/scollega un oggetto a un altro oggetto (nel caso di associazioni)
2.107
Analisi
Analisi
2.109
Analisi
Analisi
Analisi
2.112
Analisi
2.113
Analisi
2.114
Analisi
2.115
Servizio 1..* *
2.116
0..*
0..*
2.117
1..* GuestCard idGuestCard : Integer inizioValidit : Date fineValidit : Date abilitata() speseGiorno() speseTotali() elencaAcquisti()
2.118
{OR}
1 pagante
associatoA
0..*
OspiteNonPagante
2.119
Contante effettuaPagamento()
2.120
Analisi
Modello dinamico
Descrive il sistema durante il suo funzionamento Consiste nella definizione di scenari di funzionamento del sistema, in risposta a eventi esterni o in fasi particolarmente significative Diagrammi dei casi duso - evidenziano le risposte a eventi esterni Diagrammi di stato - evidenziano i possibili stati che un oggetto pu assumere gli eventi che attivano transizioni da uno stato allaltro
Ingegneria del Software T 2.121
Analisi
Modello dinamico
Diagrammi di interazione - descrivono lo scambio di messaggi tra oggetti Diagrammi di sequenza - evidenziano lordine in cui i messaggi vengono scambiati tra gli oggetti Diagrammi di collaborazione - evidenziano le connessioni tra gli oggetti e i messaggi scambiati Entro certi limiti, un diagramma di sequenza pu essere convertito nel suo corrispondente diagramma di collaborazione e viceversa
Ingegneria del Software T 2.122
Analisi
Modello dinamico
Non conviene spingere la definizione del modello dinamico sino ai minimi dettagli Utilizzare i diagrammi dinamici solo per descrivere il funzionamento del sistema nei casi pi critici La definizione dettagliata di tutte le operazioni del sistema pu essere fatta realizzando un prototipo funzionante
2.123
2.124
2.125
2.127
2.129
cliente : Package1::ClasseA
fornitore : Package1::ClasseB
messaggio1()
2.130
Le linee verticali tratteggiate (lifeline) indicano il tempo di vita degli oggetti Il flusso temporale scorre dallalto in basso Gli ispessimenti delle linee verticali denotano unelaborazione in corso possibile indicare esplicitamente quando un oggetto viene creato e quando viene distrutto
2.131
unCliente messaggio1()
unFornitore
2.132
2.133
2.134
2.135
2.136
2.137
In questi casi, opportuno disegnare un diagramma di stato per loggetto, mostrando i possibili stati e gli eventi che attivano transizioni da uno stato all'altro
Ingegneria del Software T 2.139
2.140
Pu essere:
Esterno generato nellambito del mondo reale (mouse, tastiera, arrivo ordine, passaggio qualifica, ) Interno generato da un oggetto del sistema
2.141
Signal Event
Occurs when a designated condition (usually described as a Boolean operation) becomes true Occurs after a designated period of time or at a specific time or date
2.142
TRANSIZIONE
Relazione tra due stati S1 (stato di partenza) e S2 (stato di arrivo) indicante che un oggetto inizialmente nello stato S1 in seguito al verificarsi di un particolare evento e se sono soddisfatte certe condizioni, effettuer certe azioni ed entrer nello stato S2
2.143
AZIONE
Computazione atomica (non interrompibile) associata a una transizione
ATTIVIT
Computazione non atomica (interrompibile) associata a uno stato insieme di azioni
2.144
TypingPassword
entry / setEchoVisible(false) exit / setEchoVisible(true) do / attivit
2.145
Stato1
evento [condizione] / azione
Stato2
transizione
2.146
2.147
Ritirato
Iscrizione [numero esami insufficiente] / Iscrivi allo stesso anno Iscrizione [numero esami sufficiente] / Iscrivi all'anno successivo
Laureato
SuperamentoEsameDiLaurea
Fuori Corso
2.148
APPLICAZIONE
PRESENTATION MANAGER
APPLICAZIONE
PRESENTATION LOGIC
APPLICATION LOGIC
DATA LOGIC
DATA MANAGER
Presentation Manager
Gestione dellinterazione con lutente Gestione dello schermo Gestione della tastiera Gestione del mouse
PRESENTATION MANAGER
Interfacce a caratteri
emulatori
Ingegneria del Software T 4
Data Manager
DATA MANAGER
Data Manager
File system
API di sistema
ODBMS: ObjectStore,
API proprietarie
APPLICAZIONE
Presentation Logic
APPLICAZIONE
Application Logic
APPLICAZIONE
Data Logic
PRESENTATION MANAGER
PRESENTATION MIDDLEWARE
APPLICAZIONE
PRESENTATION LOGIC
APPLICATION LOGIC
DATA LOGIC
DATABASE MIDDLEWARE
DATA MANAGER
10
Middleware
Software che permette la comunicazione tra processi API che isolano il codice dellapplicazione dai sottostanti formati e protocolli di comunicazione
11
Presentation Middleware
Software di emulazione di terminali alfanumerici Combinazione di:
Web browser (lato client) Web server Protocollo HTTP
12
Database Middleware
Software proprietario che trasferisce sulla rete
Le richieste SQL dallapplicazione al DBMS I dati dal DBMS allapplicazione
ODBC, JDBC
13
APPLICAZIONE
PRESENTATION LOGIC
APPLICATION LOGIC
APPLICATION MIDDLEWARE
APPLICAZIONE
APPLICATION LOGIC
DATA LOGIC
14
Application Middleware
Gestisce la comunicazione tra due componenti della stessa applicazione meno vincoli progettuali
Point-to-point (P2P) Remote procedure call (RPC) Message queuing middleware (MQM) Message oriented middleware (MOM), P2P + MQM Object request broker (ORB) Distributed transaction monitor (DTM)
15
DallOOA allOOD
LOOA identifica e definisce le responsabilit del sistema le classi e gli oggetti entro i limiti del dominio del problema LOOA definisce il modello statico e il modello dinamico del sistema, indipendentemente dalla specifica implementazione dalle modalit di interazione con lutente dalle modalit di persistenza degli oggetti
Ingegneria del Software T 2
DallOOA allOOD
Per realizzare un sistema funzionante, occorre considerare anche GUI DB Framework, librerie, componenti, Modifiche al modello per avere software estensibile e modulare
DallOOA allOOD
LOOD identifica e definisce altre classi e oggetti alla luce dei seguenti principi
Incapsulamento Flessibilit Evoluzione Riuso Prestazioni Massima indipendenza possibile da
Linguaggio (e ambiente) di programmazione Sistema Operativo Hardware
Si noti che mediamente le classi di analisi sono solo tra l1% e il 10% delle classi di progettazione!
Ingegneria del Software T 4
DallOOA allOOD
Il paradigma ad oggetti permette
Sia di modellare il mondo reale Sia di implementare il software
Nella fase di progettazione NON occorre creare un modello differente da quello sviluppato nella fase di analisi Si utilizza ununica notazione
Sia nella fase di analisi Sia nella fase di progettazione
Ingegneria del Software T 5
DallOOA allOOD
Durante lOOD, il modello prodotto dallOOA deve essere esteso al fine di modellare/progettare i quattro componenti principali di ogni singola applicazione che compone il sistema APPLICATION LOGIC logica dellapplicazione e controllo degli altri componenti PRESENTATION LOGIC gestione dellinterazione con lutente a livello logico nuovi oggetti: finestre, men, bottoni, toolbar, DATA LOGIC gestione della persistenza a livello logico nuovi oggetti: file, record, tabelle relazionali, transazioni, istruzioni SQL, MIDDLEWARE gestione dellinterazione con i (sotto)sistemi esterni e con la rete
Ingegneria del Software T 6
DallOOA allOOD
NellOOD, i risultati dellanalisi possono essere modificati per motivi di opportunit legati allimplementazione Le modifiche devono essere ridotte al minimo indispensabile, per mantenere il massimo accordo possibile tra OOA e OOD Principali motivi per modificare il modello OOA
Progettazione logica definizione dettagliata dellimplementazione delle classi e delle loro relazioni Riuso di classi e/o componenti disponibili Raggruppamento di classi del modello
Ingegneria del Software T 7
DallOOA allOOD
Principali motivi per modificare il modello OOA
Miglioramento delle prestazioni Aggiunta di caratteristiche specifiche
Gestione persistenza Gestione comunicazioni Diagnostica,
Supporto alla portabilit Se e solo se vincolanti, caratteristiche del linguaggio di programmazione, del S.O., dellhardware, del DBMS, ... che devono essere utilizzati
Livello di ereditariet supportato Api
Progettazione logica
Progetto dello schema logico del modello Tipi di dato Strutture dati Operazioni Mentre nellanalisi ci si concentra su cosa deve fare il sistema, nella progettazione logica ci si concentra su come deve funzionare il sistema
Progettazione logica
Il passaggio dallOOA allOOD non ben supportato dagli strumenti CASE: non c modo di separare le due fasi Due possibilit Lanalisi sfuma nella progettazione
il modello OOA viene progressivamente aumentato e completato, sino alla progettazione del sistema lanalisi originale si perde
Il modello OOD generato a partire dal modello OOA, ma viene mantenuto distinto
lanalista deve mantenere la corrispondenza tra i due modelli, in caso di modifiche che si ripercuotono sullanalisi
Ingegneria del Software T 10
Progettazione logica
Durante la progettazione logica necessario definire
Tipi di dato che non sono stati definiti nel modello OOA Determinazione della navigabilit delle associazioni tra classi e relativa implementazione Strutture dati necessarie per limplementazione del sistema Operazioni necessarie per limplementazione del sistema Algoritmi che implementano le operazioni Visibilit di classi, (attributi,) operazioni,
11
Navigabilit di unassociazione
Possibilit di spostarsi da un qualsiasi oggetto della classe origine a uno o pi oggetti della classe destinazione (a seconda della molteplicit) I messaggi possono essere inviati solo nella direzione della freccia
Ogni docente deve avere un riferimento al proprio dipartimento di afferenza
Ogni dipartimento deve avere un riferimento al proprio direttore Ingegneria del Software T 12
Navigabilit di unassociazione
A livello di analisi, le associazioni di contenimento e di aggregazione hanno una direzione precisa detti A il contenitore e B loggetto contenuto, A che contiene B, e non viceversa A livello implementativo, unassociazione pu essere mono-direzionale quando da A si deve poter accedere a B, ma non viceversa bi-direzionale quando da A si deve poter accedere a B e da B si deve poter accedere velocemente ad A
13
Navigabilit di unassociazione
Dal punto di vista implementativo, la bi-direzionalit
molto efficiente ma occorre tenere sotto controllo la consistenza delle strutture dati utilizzate per la sua implementazione
Ogni dipartimento deve avere i riferimenti a tutti i suoi docenti Ogni docente deve avere un riferimento al proprio dipartimento di afferenza
14
15
Valuta FormaDiPagamento idValuta : String effettuaPagamento() * 1 idValuta : String cambio : Double dataAggiornamento : Date aggiornaCambio()
16
17
Servizio 1..* *
PuntoVendita idPuntoVendita idProgressivo : Integer servizi : Servizi importoVenditeGiorno() importoVenditeTotale() creaMovimento() elencaVendite()
Servizio 1..* *
Servizi 1 1
18
19
20
21
PuntoVendita * 1..*
22
Classi contenitore
Una classe contenitore (o semplicemente contenitore) una classe le cui istanze contengono oggetti di altre classi Se gli oggetti contenuti sono in numero fisso e non richiesto un particolare ordine, pu essere sufficiente un vettore predefinito del linguaggio Se gli oggetti contenuti sono in numero variabile o hanno un ordine da mantenere, allora un vettore predefinito non basta e occorre una classe contenitore Esempi di classi contenitore sono Vettori, stack, liste, alberi,
23
Classi contenitore
Funzionalit minime di una classe contenitore Memorizzare (e quindi tenere insieme) gli oggetti della collezione Aggiungere un oggetto alla collezione Togliere un oggetto dalla collezione Trovare un oggetto in una collezione Enumerare (iterare su) gli oggetti della collezione I contenitori possono essere classificati in funzione del modo in cui contengono gli oggetti dellomogeneit o eterogeneit di tali oggetti
24
25
26
27
28
Classi generiche
Classi in cui uno o pi tipi (e/o valori) sono parametrici Ogni istanza di una classe generica costituisce una classe indipendente non esiste un legame di ereditariet
T Vettore
bind (Integer)
Vettore<Integer> VettoreDiInteri
29
31
33
34
T Vector bind(Servizio)
* Servizi
1..* Servizio
35
36
Esempio 2
Ingegneria del Software T 37
38
1 CatenaPuntiVendita
1
PuntoVendita
: PuntoVendita : PuntoVendita
chiave
valore
: CatenaPuntiVendita
: CatenaPuntiVendita : PuntoVendita
39
40
41
Un esempio reale
La tecnologia COM (MS) permette a unapplicazione di trovare, caricare e utilizzare run-time i componenti necessari per la sua esecuzione Ogni componente memorizzato in una DLL (Dynamic Link Library) un file locale o remoto Quando lapplicazione ha bisogno di un componente, il sistema deve essere in grado di localizzare la DLL che contiene quel particolare componente
42
Un esempio reale
Lindipendenza dalla collocazione fisica non consente di utilizzare un indirizzo fisico (pathname) Pertanto, deve essere utilizzato un meccanismo di indirizzamento logico che permetta di identificare univocamente il file che contiene il componente Si utilizzano degli identificatori globali (GUID = Globally Unique Identifier)
43
Un esempio reale
Il concetto di GUID stato introdotto, con un nome leggermente diverso (UUID = Universally Unique Identifier), dallOSF (Open Software Foundation) nelle specifiche DCE (Distributed Computing Environment) In DCE gli UUID vengono utilizzati per identificare i destinatari delle chiamate di procedura remota (RPC)
44
Un esempio reale
Un GUID un numero di 128 bit (16 byte) generato in modo da garantire lunicit nello spazio e nel tempo: MAC (48/64 bit) + ticks (64 bit 100ns) rappresentato cos: {32bb8320-b41b-11cf-a6bb-0080c7b2d682} COM utilizza diversi tipi di GUID Il tipo pi importante di GUID serve a identificare le classi di componenti: ogni classe di componenti COM caratterizzata da un proprio identificatore che viene chiamato CLSID (Class Identifier)
Ingegneria del Software T 45
Un esempio reale
Disponendo di un CLSID, unapplicazione pu chiedere alla funzione di sistema CoCreateInstance di creare un istanza del componente e di restituire un riferimento nel spazio di indirizzamento dellapplicazione stessa Il database di sistema di Windows (registry) mantiene una corrispondenza tra CLSID ed entit fisiche (DLL, EXE) che contengono limplementazione dei componenti (server)
46
Un esempio reale
CoCreateInstance provvede a reperire il server tramite il registry caricarlo in memoria (se non gi presente) creare unistanza e restituirne un riferimento
47
Un esempio reale
In .NET esiste la classe System.Guid che permette di gestire istanze di GUID Ad esempio, per ottenere un nuovo GUID, sufficiente invocare il metodo statico Guid.NewGuid() che, ovviamente, restituisce un System.Guid Altri metodi e operatori permettono di confrontare GUID
48
49
50
52
54
57
58
necessario convertire le strutture con ereditariet multipla in strutture con solo ereditariet semplice
59
Delfino
60
61
Delfino
0,1 1
62
63
64
Questo tipo di modifica deve essere presa in considerazione solo dopo che tutti gli altri aspetti del progetto sono stati soggetti a misure e modifiche
Lunico modo per sapere se una modifica contribuir in modo significativo a rendere il software abbastanza veloce tramite le misure e losservazione
Ingegneria del Software T 66
Design Principles
Design quality
Design quality is an elusive concept Quality depends on specific organisational priorities A good design may be
the most reliable, the most efficient, the most maintainable, the cheapest,
The attributes discussed here are concerned with the maintainability of the design
Software Rigidity
The tendency for software to be difficult to change Symptom: every change causes a cascade of subsequent changes in dependent modules Effect: managers fear to allow developers to fix non-critical problems they dont know when the developers will be finished
Software Fragility
The tendency of the software to break in many places every time it is changed changes tend to cause unexpected behavior in other parts of the system (often in areas that have no conceptual relationship with the area that was changed) Symptom: every fix makes it worse, introducing more problems than are solved such software is impossible to maintain Effect: every time managers authorize a fix, they fear that the software will break in some unexpected way
Software Immobility
The inability to reuse software from other projects or from parts of the same project Symptom: a developer discovers that he needs a module that is similar to one that another developer wrote. But the module in question has too much baggage that it depends upon. After much work, the developer discovers that the work and risk required to separate the desirable parts of the software from the undesirable parts are too great to tolerate Effect: and so the software is simply rewritten instead of reused
Viscosity
Developers usually find more than one way to make a change: some preserve the design, others do not (i.e. they are hacks) The tendency to encourage software changes that are hacks rather than software changes that preserve original design intent Viscosity of design: the design preserving methods are harder to employ than the hacks Viscosity of environment: the development environment is slow and inefficient (compile times are very long, source code control system requires hours to check in just a few files, ) Symptom: it is easy to do the wrong thing, but hard to do the right thing Effect: the software maintainability degenerates due to hacks, workarounds, shortcuts, temporary fixes,
7 Ingegneria del Software T - Design Principles
Not so obvious:
software rotting is a slow process even originally clean and elegant design may degenerate over the months/years requirements often change in the way the original design or designer did not anticipate unplanned and improper module dependencies creep in dependencies go unmanaged
Requirement Changes
We, as software engineers, know full well that requirements change Indeed, most of us realize that the requirements document is the most volatile document in the project If our designs are failing due to the constant rain of changing requirements, it is our designs that are at fault We must somehow find a way to make our designs resilient to such changes and protect them from rotting
Dependency Management
Each of the four symptoms mentioned above is either directly, or indirectly caused by improper dependencies between the modules of the software It is the dependency architecture that is degrading, and with it the ability of the software to be maintained In order to forestall the degradation of the dependency architecture, the dependencies between modules in an application must be managed Object Oriented Design is replete with principles and techniques for managing module dependencies
10
Design Principles
The Single Responsibility Principle (SRP) The Open/Closed Principle (OCP) The Dependency Inversion Principle (DIP) The Liskov Substitution Principle (LSP) The Interface Segregation Principle (ISP)
11
Premessa
Il principio zero
Il principio zero un principio di logica noto come rasoio di Occam: Entia non sunt multiplicanda praeter necessitatem ovvero: non bisogna introdurre concetti che non siano strettamente necessari la forma colta di un principio pratico: Quello che non c non si rompe (H. Ford) Tra due soluzioni bisogna preferire quella che introduce il minor numero di ipotesi e che fa uso del minor numero di concetti
12
Premessa
Semplicit e semplicismo
La semplicit un fattore importantissimo il software deve fare i conti con una notevole componente di complessit, generata dal contesto in cui deve essere utilizzato quindi estremamente importante non aggiungere altra complessit arbitraria Il problema che la semplicit richiede uno sforzo non indifferente ( molto pi facile essere complicati che semplici) in generale le soluzioni pi semplici vengono in mente per ultime Bisogna fare poi molta attenzione ad essere semplici ma non semplicistici Keep it as simple as possible but not simpler (A. Einstein)
13
Premessa
Divide et impera
La decomposizione una tecnica fondamentale per il controllo e la gestione della complessit Non esiste un solo modo per decomporre il sistema la qualit della progettazione dipende direttamente dalla qualit delle scelte di decomposizione adottate In questo contesto il principio fondamentale : minimizzare il grado di accoppiamento tra i moduli del sistema Da questo principio possibile ricavare diverse regole: minimizzare la quantit di interazione fra i moduli eliminare tutti i riferimenti circolari fra moduli
14 Ingegneria del Software T - Design Principles
15
Example
Example
17
Example Refactoring
A better design is to separate the two responsibilities into two completely different classes
Extract Class: create a new class and move the relevant fields and methods from the old class into the new class
+ draw()
18
19
Software entities (classes, modules, functions, ) should be open for extension, but closed for modification
Open:
May be extended by adding new state or behavioral properties
Closed:
Has a well-defined, published and stable interface which may not be changed
20
21
22
Esempio 1
23
Esempio 1
Client is closed to changes in implementation of IServer Client is open for extension through new IServer implementations Without IServer the Client is open to changes in Server
24 Ingegneria del Software T - Design Principles
Esempio 1
25
Esempio 2
ShapeData
shap eType : int
public void drawShape(ShapeData shapeData) { switch (shapeData.shapeType) { ca se SQUARE: drawSquare((SquareData)shapeData); break; ca se CIRC LE: drawCircle((CircleData)shapeData); break; } }
ShapeManipulator
dra wSh ape(s hapeData : ShapeData) dra wC ircle(circle : Circl eData) dra wSq uare(square : SquareData )
26
Esempio 2
If I need to create a new shape, such as a Triangle, I must modify drawShape In a complex application the switch/case statement above is repeated over and over again for every kind of operation that can be performed on a shape Worse, every module that contains such a switch/case statement retains a dependency upon every possible shape that can be drawn, thus, whenever one of the shapes is modified in any way, the modules all need recompilation, and possibly modification
27
Esempio 2
SmartShapeManipulator
drawShap e(shape : Sha peInterface)
28
Even if the OCP cannot be fully achieved, even partial OCP compliance can make dramatic improvements in the structure of an application
29
30
Preconditions
The properties that must be true prior to any attempt to use a particular service
Postconditions
The properties that are guaranteed to exist after the service is performed, if it operates without error
31
Module A
Module B
Module B Module C Cs data
Module C
Module D
Bs data
Module D Ds data
32
33
34
35
36
HighLevelFn1
HighLevelFn2
HighLevelFn3
LowLevelFn1
LowLevelFn2
LowLevelFn3
LowLevelFn4
37
DetailImpl1
DetailImpl2
DetailImpl3
38
39
Esempio 1
Consider a simple program that is charged with the task of copying characters typed on a keyboard to a printer Assume, furthermore, that the implementation platform does not have an operating system that supports device independence
void Copy() { int c; while ((c = ReadKeyboard()) != EOF) WritePrinter(c); }
40
Esempio 1
The two low level modules are reusable: they can be used in many other programs to gain access to the keyboard and the printer this is the same kind of reusability that we gain from subroutine libraries The Copy module is not reusable in any context which does not involve a keyboard or a printer This is a shame since the intelligence of the system is maintained in this module it is the Copy module that encapsulates a very interesting policy that we would like to reuse
41 Ingegneria del Software T - Design Principles
Esempio 1
Consider a new program that copies keyboard characters to a disk file We could modify the Copy module to give it the new desired functionality As time goes on, and more and more devices must participate in the copy program, the Copy module will be littered with if/else statements and will be dependent upon many lower level modules it will eventually become rigid and fragile
enum OutputDevice { Printer, Disk }; void Copy(OutputDevice dev) { int c; while ((c = ReadKeyboard()) != EOF) { if (dev == Printer) WritePrinter(c); else WriteDisk(c); } }
42
Esempio 1
One way to characterize the problem above is to notice that the module containing the high level policy (Copy) is dependent upon the low level detailed modules that it controls (WritePrinter and ReadKeyboard) If we could find a way to make the Copy module independent of the details that it controls, then
we could reuse it freely we could produce other programs which used this module to copy characters from any input device to any output device
43
Esempio 1
interface Reader { int Read(); } interface Writer { void Write(char); } void Copy(Reader r, Writer w) { int c; while ((c = r.Read()) != EOF) w.Write(c); }
44
Esempio 2
45
Esempio 2
46
Dipendenze transitive
...all well structured object-oriented architectures have clearly-defined layers, with each layer providing some coherent set of services though a well-defined and controlled interface (Grady Booch) I sistemi software dovrebbero essere stratificati, cio organizzati a livelli Le dipendenze transitive devono essere eliminate
Policy Layer
Depends on
Mechanism Layer
Depends on
Utility Layer
47
Dipendenze transitive
Policy Layer
Depends on
Utility Interface
Utility Layer
48
49
Example
Policy
getUnitsOfRisk() getPolicyCoverages() getRateSteps()
PolicyRateModule
HomeOwnerPolicy
Aut oP olicy
This module should not break regardless of whether a Personal Auto or Commercial Auto or Home Owner Policy is passed to it
PersonalAutoPolicy
CommercialAutoPolicy
50
Example
51
52
Design by Contract
Nel Design by Contract ogni metodo ha un insieme di pre-condizioni requisiti minimi che devono essere soddisfatti dal chiamante perch il metodo possa essere eseguito correttamente un insieme di post-condizioni requisiti che devono essere soddisfatti dal metodo nel caso di esecuzione corretta Questi due insiemi di condizioni costituiscono un contratto tra chi invoca il metodo (cliente) e il metodo stesso (e quindi la classe a cui appartiene) Le pre-condizioni vincolano il chiamante Le post-condizioni vincolano il metodo Se il chiamante garantisce il verificarsi delle pre-condizioni, il metodo garantisce il verificarsi delle post-condizioni
53
Design by Contract
Quando un metodo viene ridefinito in una sottoclasse le pre-condizioni devono essere identiche o meno stringenti le post-condizioni devono essere identiche o pi stringenti Questo perch un cliente che invoca il metodo conosce il contratto definito a livello della classe base, quindi non in grado: di soddisfare pre-condizioni pi stringenti o di accettare post-condizioni meno stringenti In caso contrario, il cliente dovrebbe conoscere informazioni sulla classe derivata e questo porterebbe a una violazione del principio di Liskov
54
Design by Contract
public class BaseClass { public virtual int Calculate(int val) { Precondition(-10000 <= val && val <= 10000); int result = val / 100; Postcondition(-100 <= result && result <= 100); return result; } } public class SubClass : BaseClass { public override int Calculate(int val) { Precondition(-20000 <= val && val <= 20000); int result = Math.Abs(val) / 200; Postcondition(0 <= result && result <= 100); return result; } }
55
Il Quadrato un Rettangolo?
public class Rectangle { private double _width; private double _height; public double Width { get { return _width; } set { _width = value; } } public double Height { get { return _height; } set { _height = value; } } public double Area { get { return Width * Height; } } }
Imagine that this application works well, and is installed in many sites As is the case with all successful software, as its users needs change, new functions are needed Imagine that one day the users demand the ability to manipulate squares in addition to rectangles
56
Il Quadrato un Rettangolo?
Inheritance is the IsA relationship In other words, if a new kind of object can be said to fulfill the IsA relationship with an old kind of object, then the class of the new object should be derived from the class of the old object Clearly, a square is a rectangle for all normal intents and purposes Since the IsA relationship holds, it is logical to model the Square class as being derived from Rectangle
57
Il Quadrato un Rettangolo?
This use of the IsA relationship is considered by many to be one of the fundamental techniques of Object Oriented Analysis A square is a rectangle, and so the Square class should be derived from the Rectangle class However this kind of thinking can lead to some subtle, yet significant, problems Generally these problem are not foreseen until we actually try to code the application
58
Il Quadrato un Rettangolo?
public class Square : Rectangle { public new double Width { get { return base.Width; } set { base.Width = value; base.Height = value; } } public new double Height { get { return base.Height; } set { base.Height = value; base.Width = value; } } }
necessario ridefinire le propriet Width e Height Notevoli differenze tra Java e C++ / C# In Java tutti i metodi sono virtuali In C++ / C# possibile definire
sia metodi virtuali, sia metodi non virtuali (non polimorfici)
59
Il Quadrato un Rettangolo?
Square s = new Square(); s.Width = 5; // 5 x 5 Method1(s); // ? void Method1(Rectangle r) { r.Width = 10; }
If we pass a reference to a Square object into Method1, the Square object will be corrupted because the height wont be changed (!) This is a clear violation of LSP Method1 does not work for derivatives of its arguments The reason for the failure is that Width and Height were not declared virtual in Rectangle
60
Il Quadrato un Rettangolo?
public class Rectangle { public virtual double Width { } public virtual double Height { } }
public class Square : Rectangle { public override double Width { } public override double Height { } }
We can fix this easily However, when the creation of a derived class causes us to make changes to the base class, it often implies that the design is faulty Indeed, it violates the OCP We might counter this with argument that forgetting to make Width and Height virtual was the real design flaw, and we are just fixing it now However, this is hard to justify since setting the height and width of a rectangle are exceedingly primitive operations by what reasoning would we make them virtual if we did not anticipate the existence of square
61
Il Quadrato un Rettangolo?
At this point in time we have two classes, Square and Rectangle, that appear to work No matter what you do to a Square object, it will remain consistent with a mathematical square And regardless of what you do to a Rectangle object, it will remain a mathematical rectangle Moreover, you can pass a Square into a function that accepts a reference to a Rectangle, and the Square will still act like a square and will remain consistent Thus, we might conclude that the model is now self consistent, and correct However, a model that is self consistent is not necessarily consistent with all its users!
62
Il Quadrato un Rettangolo?
public void Scale(Rectangle rectangle) { rectangle.Width = rectangle.Width * ScalingFactor; rectangle.Height = rectangle.Height * ScalingFactor; }
Scale invokes members of what it believes to be a Rectangle Substituing a Square into this will result in the square being scaled twice! So here is the real problem: was the programmer who wrote Scale justified in assuming that changing the width of a Rectangle leaves its height unchanged?
63
Il Quadrato un Rettangolo?
Clearly, the programmer of Scale made this very reasonable assumption Passing a Square to functions whose programmers made this assumption will result in problems Therefore, there exist functions that take references to Rectangle objects, but cannot operate properly upon Square objects These functions expose a violation of the LSP The addition of the Square derivative of Rectangle has broken these function the OCP has been violated
64
Il Quadrato un Rettangolo?
Why did the model of the Square and Rectangle go bad After all, isnt a Square a Rectangle? Doesnt the IsA relationship hold? No! A square might be a rectangle, but a Square object is definitely not a Rectangle object Why? Because the behavior of a Square object is not consistent with the behavior of a Rectangle object Behaviorally, a Square is not a Rectangle! And it is behavior that software is really all about
65
Il Quadrato un Rettangolo?
The LSP makes clear that in OOD the IsA relationship pertains to behavior. Not intrinsic private behavior, but extrinsic public behavior; behavior that clients depend upon For example, the author of Scale depended on the fact that rectangles behave such that their height and width vary independently of one another. That independence of the two variables is an extrinsic public behavior that other programmers are likely to depend upon In order for the LSP to hold, and with it the OCP, all derivatives must conform to the behavior that clients expect of the base classes that they use
66
Il Quadrato un Rettangolo?
The rule for the preconditions and postconditions for derivatives, is: when redefining a routine, you may only replace its precondition by a weaker one, and its postcondition by a stronger one In other words, when using an object through its base class interface, the user knows only the preconditions and postconditions of the base class Thus, derived classes must not expect such users to obey preconditions that are stronger then those required by the base class they must accept anything that the base class could accept Also, derived classes must conform to all the postconditions of the base class their behaviors and outputs must not violate any of the constraints established for the base class
67
Il Quadrato un Rettangolo?
The contract of Rectangle height and width are independent, can set one while the other remains unchanged Square violates the contract of the base class
68
Il Quadrato un Rettangolo?
If we look at the test fixture for our Rectangle we get some idea of the contract for a Rectangle:
[TestFixture] public class RectangleFixture { [Test] public void SetHeightAndWidth() { Rectangle rectangle = new Rectangle(); int expectedWidth = 3, expectedHeight = 7; rectangle.Width = expectedWidth; rectangle.Height = expectedHeight; Assertion.AssertEquals(expectedWidth, rectangle.Width); Assertion.AssertEquals(expectedHeight, rectangle.Height); } }
69
Il Quadrato un Rettangolo?
[TestFixture] public class RectangleFixture { [Test] public void SetHeightAndWidth() { Rectangle rectangle = GetShape(); ... } protected virtual Rectangle GetShape() { return new Rectangle(); } } [TestFixture] public class SquareFixture : RectangleFixture { protected override Rectangle GetShape() { return new Square(); } }
70
71
ClientC
72
ClientB
<<Interface>> ClientBService
clientBMethods()
ServiceImpl
clientAMethods() clientBMethods() clientCMethods()
ClientC
<<Interface>> ClientCService
clientCMethods()
73
74
75
76
77
78
79
Discussion
These three cannot simultaneously be satisfied The REP and CRP makes life easy for re-users, whereas the CCP makes life easier for maintainers The CCP strives to make packages as large as possible (after all, if all the classes live in just one package, then only one package will ever change). The CRP, however, tries to make packages very small Early in a project, architects may set up the package structure such that CCP dominates for ease of development and maintenance. Later, as the architecture stabilizes, the architects may re-factor the package structure to maximize REP and CRP for the external re-users
80
81
82
comm
process
modem
protocol
file
comm_error
83
comm
process
modem
protocol
file
comm_error
84
Discussion
In the acyclic scenario to release the protocol package, the engineers would have to build it with the latest release of the comm_error package, and run their tests In the cyclic scenario to release the protocol package, the engineers would have to build it with the latest release of the comm_error, gui, comm, process, modem, file and run their tests Breaking the cycle:
Add new package in between Add a new Interface
85
implements
BInterface
86
87
Example
A B C
88
Discussion
The packages at the top are instable and flexible The packages at the bottom are very difficult to change The highly stable packages at the bottom of the dependency network may be very difficult to change, but according to the OCP they do not have to be difficult to extend. If the stable packages at the bottom are also highly abstract, then they can be easily extended It is possible to compose our application from instable packages that are easy to change, and stable packages that are easy to extend
89
Design Pattern
Design Pattern
Nel 1977, Christopher Alexander disse: "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use the solution a million times over, without ever doing it the same way twice" Parlava di costruzioni civili e di citt
2 Ingegneria del Software T - Design Pattern
Design Pattern
La stessa frase applicabile anche alla progettazione object-oriented In questo caso, le soluzioni utilizzeranno
oggetti, classi e interfacce invece che pareti e porte
Design Pattern
Obiettivi Risolvere problemi progettuali specifici Rendere i progetti object-oriented pi flessibili e riutilizzabili Ogni design pattern Cattura e formalizza lesperienza acquisita nellaffrontare e risolvere uno specifico problema progettuale Permette di riutilizzare tale esperienza in altri casi simili
Design Pattern
Ogni design pattern ha quattro elementi essenziali un nome (significativo) identifica il pattern il problema descrive quando applicare il pattern la soluzione descrive il pattern, cio gli elementi che lo compongono (classi e istanze) e le loro relazioni, responsabilit e collaborazioni le conseguenze descrivono vantaggi e svantaggi dellapplicazione del pattern Permettono di valutare le alternative progettuali
Pattern strutturali
Adapter Bridge Composite Decorator Facade Flyweight Proxy
Pattern comportamentali
Chain of Responsability Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor
Pattern SINGLETON
Assicura che una classe abbia una sola istanza e fornisce un punto di accesso globale a tale istanza La classe deve:
tenere traccia della sua sola istanza intercettare tutte le richieste di creazione, al fine di garantire che nessuna altra istanza venga creata fornire un modo per accedere allistanza unica
Pattern SINGLETON
public class Singleton { attributi membro di istanza private static Singleton _instance = null; protected Singleton() { inizializzazione istanza } public static Singleton GetInstance() { if(_instance == null) _instance = new Singleton(); return _instance; } metodi pubblici, protetti e privati }
9 Ingegneria del Software T - Design Pattern
Pattern SINGLETON
Alternativa: classe non istanziabile con soli membri statici Perch un singleton?
Creo il singleton (e quindi lo inizializzo) solo la prima volta che mi serve Gli attributi membro di classe vengono inizializzati in un ordine non definito prima che il controllo passi al main (eccezione: costruttore statico in C#) Posso specializzare il singleton e creare nella GetInstance una istanza specializzata che dipende dal contesto corrente
10
Pattern SINGLETON
public static Singleton GetInstance() { if(_instance == null) _instance = CreateInstance(); return _instance; } private static { if() return new else if() return new else return new }
11
Singleton CreateInstance()
Pattern FLYWEIGHT
Descrive come condividere oggetti leggeri (cio a granularit molto fine) in modo tale che il loro uso non sia troppo costoso Un flyweight un oggetto condiviso che pu essere utilizzato simultaneamente ed efficientemente da pi clienti (del tutto indipendenti tra loro) Bench condiviso, non deve essere distinguibile da un oggetto non condiviso Non deve fare ipotesi sul contesto nel quale opera
12
Pattern FLYWEIGHT
Distinzione tra stato intrinseco e stato estrinseco Stato intrinseco Non dipende dal contesto di utilizzo e quindi pu essere condiviso da tutti i clienti Memorizzato nel flyweight Stato estrinseco Dipende dal contesto di utilizzo e quindi non pu essere condiviso dai clienti Memorizzato nel cliente o calcolato dal cliente Viene passato al flyweight quando viene invocata una sua operazione
13 Ingegneria del Software T - Design Pattern
Pattern FLYWEIGHT
Per assicurare una corretta condivisione, i clienti non devono istanziare direttamente i flyweight ma devono ottenerli esclusivamente tramite una FlyweightFactory GetFlyweight(key) { if(flyweights[key] not exist) create flyweights[key] return flyweights[key] }
14
Pattern FLYWEIGHT
Gestisce lo stato estrinseco Dichiara uninterfaccia tramite la quale i flyweight possono ricevere dal cliente lo stato estrinseco e operare
15
16
Lo stato estrinseco (memorizzato nel cliente) comprender il contesto in cui licona dovr essere disegnata (dipendente dal singolo cliente):
Posizione dellicona Dimensioni richieste,
Esempio
17 Ingegneria del Software T - Design Pattern
Pattern STRATEGY
Permette di
definire un insieme di algoritmi tra loro correlati, incapsulare tali algoritmi in una gerarchia di classi e rendere gli algoritmi intercambiabili
Client ClientInterface() * 1 interface Strategy Algorithm()
18
Pattern STRATEGY
Dichiara uninterfaccia comune a tutti gli algoritmi supportati
Client ClientInterface() * 1
Referenzia loggetto che implementa un algoritmo Pu dichiarare uninterfaccia che permetta alloggetto Strategy di accedere ai dati del cliente
19 Ingegneria del Software T - Design Pattern
20
Paragraph utilizza i servizi di un Aligner specificato dinamicamente run-time possibile realizzare gli Aligner utilizzando il pattern flyweight
Esempio
21 Ingegneria del Software T - Design Pattern
Pattern ADAPTER
Converte linterfaccia originale di una classe nellinterfaccia (diversa) che si aspetta il cliente Permette a classi che hanno interfacce incompatibili di lavorare insieme Si usa quando si vuole riutilizzare una classe esistente e la sua interfaccia non conforme a quella desiderata Noto anche come wrapper
22
Pattern ADAPTER
Utilizza loggetto tramite linterfaccia di Target
Target Client Operation()
Adapter Operation()
adaptee 1
adaptee
Adaptee SpecificOperation()
adaptee.SpecificOperation()
23
Pattern ADAPTER
In C++, si potrebbe scrivere:
class Adapter : public Target, private Adaptee
Cio ereditare linterfaccia di Target e limplementazione di Adaptee In un linguaggio in cui non ammesso ereditare limplementazione, conviene utilizzare la composizione
Esempio
24 Ingegneria del Software T - Design Pattern
Pattern DECORATOR
Permette di aggiungere responsabilit a un oggetto dinamicamente Fornisce unalternativa flessibile alla specializzazione
In alcuni casi, le estensioni possibili sono talmente tante che per poter supportare ogni possibile combinazione, si dovrebbe definire un numero troppo elevato di sottoclassi
25
Pattern DECORATOR
TextBox
BorderTextBox FilledTextBox VerticalTextBox BorderFilledTextBox BorderVerticalTextBox BorderFilledVerticalTextBox FilledVerticalTextBox
E se volessi
2 o pi bordi Cambiare il font
26
Pattern DECORATOR
Component Operation() 1
component
ConcreteComponent Operation()
Decorator Operation()
component * component.Operation()
base.Operation() AddedBehaviour()
27
Pattern DECORATOR
Component (interfaccia o classe astratta)
Dichiara linterfaccia di tutti gli oggetti ai quali deve essere possibile aggiungere dinamicamente responsabilit
ConcreteComponent
Definisce un tipo di oggetto al quale deve essere possibile aggiungere dinamicamente responsabilit
ConcreteDecorator
Aggiunge responsabilit al componente referenziato
28 Ingegneria del Software T - Design Pattern
Pattern DECORATOR
interface IComponent 1
component
BorderedFrame
FilledFrame
VerticalTextFrame
Bordered
Filled
Text
Bordered
Bordered
Esempio
29
Ereditariet dinamica
Una sotto-classe deve sempre essere una versione pi specializzata della sua super-classe (o classe base) Un buon test sul corretto utilizzo dellereditariet che sia valido il principio di sostituibilit di Liskov: B una sotto-classe di A se e solo se ogni programma che utilizzi oggetti di classe A pu utilizzare oggetti di classe B senza che il comportamento logico del programma cambi Perch ci sia valido, necessario che:
le pre-condizioni di tutti i metodi della sotto-classe siano uguali o pi deboli le post-condizioni di tutti i metodi della sotto-classe siano uguali o pi forti ogni metodo ridefinito nella sotto-classe deve mantenere la semantica del metodo originale
30 Ingegneria del Software T - Design Pattern
Ereditariet dinamica
Rettangolo + property Altezza : double + property Larghezza : double - _altezza : double - _larghezza : double + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( ) use ModificatoreDiDimensioni + Modifica ( )
Esempio S1
Un quadrato un rettangolo con la sola differenza che altezza e larghezza devono essere uguali Un quadrato ha un vincolo in pi rispetto al rettangolo
Quadrato + property Altezza : double + property Larghezza : double + property Lato : double + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( ) + get Lato ( ) + set Lato ( )
31
Ereditariet dinamica
Il metodo Modifica della classe ModificatoreDiDimensioni
funziona correttamente su un Rettangolo ma NON funziona correttamente su un Quadrato
Quindi non possibile passare unistanza di Quadrato dove prevista unistanza di Rettangolo (il principio di sostituzione di Liskov violato!) Conclusione: un quadrato NON un rettangolo perch pone dei nuovi vincoli al concetto di rettangolo Come possiamo tenere conto di ci che il rettangolo e il quadrato hanno in comune?
32 Ingegneria del Software T - Design Pattern
Ereditariet dinamica
interface IParallelogramma + property Altezza : double + property Larghezza : double + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( )
Esempio S2
Quadrato + property Altezza : double + property Larghezza : double + property Lato : double - _lato : double + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( ) + get Lato ( ) + set Lato ( )
Rettangolo + property Altezza : double + property Larghezza : double - _altezza : double - _larghezza : double + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( ) ModificatoreDiDimensioni use + Modifica ( )
33
Ereditariet dinamica
Cosa intendiamo esattamente per Rettangolo e per Quadrato? Rettangolo: parallelogramma i cui angoli sono retti Parallelogramma: quadrilatero i cui lati opposti sono paralleli tra loro Quadrilatero: poligono avente quattro lati e quattro angoli
Quadrilateri notevoli sono il quadrato, il rettangolo, il parallelogramma, il rombo e il trapezio
Poligono: figura geometrica limitata da una linea poligonale chiusa Rombo: parallelogramma equilatero in cui gli angoli adiacenti sono diversi tra loro Quadrato: parallelogramma equilatero ed equiangolo
34
Ereditariet dinamica
Cosa intendiamo esattamente per Rettangolo e per Quadrato nella nostra applicazione? Ipotesi: abbiamo a che fare esclusivamente con parallelogrammi
1. Lati e angoli NON sono modificabili
Definisco quattro classi concrete che derivano dalla classe astratta Parallelogramma (o implementano IParallelogramma): Rettangolo, Quadrato, Rombo, ParallelogrammaGenerico Uso una factory che in base ai valori dei lati e degli angoli mi istanzia un rettangolo (che NON deve avere i lati uguali), un quadrato, un rombo o un parallelogramma generico
35
Ereditariet dinamica
2. Lati e angoli sono modificabili
Definisco ununica classe concreta Parallelogramma le cui istanze possono comportarsi a seconda del loro stato come: un rettangolo, un quadrato, un rombo, o un parallelogramma generico
36
Ereditariet dinamica
Come pu un oggetto cambiare comportamento, al cambiare del suo stato? 1a possibilit: si cambia la classe delloggetto run-time nella maggior parte dei linguaggi di programmazione a oggetti, questo non possibile (inoltre, meglio che un oggetto non possa cambiare classe durante la sua esistenza la classe di un oggetto deve basarsi sulla sua essenza e non sul suo stato) 2a possibilit: si utilizza il pattern State che usa un meccanismo di delega, grazie al quale loggetto in grado di comportarsi come se avesse cambiato classe
37
Pattern STATE
Context + Operation ( ) - _state AbstractState 1 + Handle ( )
Localizza il comportamento specifico di uno stato e suddivide il comportamento in funzione dello stato Le classi concrete contengono la logica di transizione da uno stato allaltro Permette anche di emulare lereditariet multipla
38
Pattern STATE
ModificatoreDiDimensioni + Modifica ( ) use Parallelogramma + property Altezza : double + property Larghezza : double + property Nome : string + property Colore : Color - _altezza : double - _larghezza : double + Parallelogramma ( ) - StateChanged ( ) + get Altezza ( ) + set Altezza ( ) + get Larghezza ( ) + set Larghezza ( ) + get Nome ( ) + get Colore ( ) - _tipo
Tipo
+ property Nome : string + property Colore : Color + DeterminaTipo ( )
TipoRettangolo + property Nome : string + property Colore : Color + get Nome ( ) + get Colore ( )
TipoQuadrato + property Nome : string + property Colore : Color + get Nome ( ) + get Colore ( )
Esempio S3
39 Ingegneria del Software T - Design Pattern
Pattern COMPOSITE
Permette di comporre oggetti in una struttura ad albero, al fine di rappresentare una gerarchia di oggetti contenitori-oggetti contenuti Permette ai clienti di trattare in modo uniforme oggetti singoli e oggetti composti
children
40
Pattern COMPOSITE
Component (classe astratta)
Dichiara linterfaccia Realizza il comportamento di default
Client
Accede e manipola gli oggetti della composizione attraverso linterfaccia di Component
children
41
Pattern COMPOSITE
Leaf
Descrive oggetti foglia cio senza figli Definisce il comportamento di tali oggetti
Composite
Descrive oggetti che hanno figli contenitori Definisce il comportamento di tali oggetti
children
42
Pattern COMPOSITE
* Component child children 0..1 *
Il contenitore dei figli deve essere un attributo di Composite e pu essere di qualsiasi tipo (array, lista, albero, tabella hash, )
43
Pattern COMPOSITE
Riferimento esplicito al genitore (parent)
Semplifica lattraversamento e la gestione della struttura Lattributo che contiene il riferimento al genitore e la relativa gestione devono essere posti nella classe Component Invariante Tutti gli elementi che hanno come parent lo stesso componente devono essere (gli unici) figli di quel componente incapsulare lassegnamento di parent nei metodi Add e Remove della classe Composite, oppure incapsulare le operazioni di Add e Remove nella set dellattributo parent della classe Component
44
Pattern COMPOSITE
public class Composite : Component { public void Add(Component aChild) { if(aChild.Parent != null) throw new ArgumentException(); _children.Add(aChild); aChild._parent = this; } }
45
Pattern COMPOSITE
public class Composite : Component { public void Remove(Component aChild) { if(aChild.Parent != this) throw new ArgumentException(); if(!_children.Contains(aChild)) throw new ArgumentException(); _children.Remove(aChild); aChild._parent = null; } }
Ingegneria del Software T - Design Pattern
46
Pattern COMPOSITE
public class Component { public Composite Parent { get { return _parent; } set { if(value != _parent) { if(_parent != null) _parent.Remove(this); if(value != null) value.Add(this); } } } }
47 Ingegneria del Software T - Design Pattern
Pattern COMPOSITE
Massimizzazione dell'interfaccia Component Un obiettivo del pattern Composite quello di fare in modo che il cliente veda solo linterfaccia di Component in Component devono essere inserite tutte le operazioni che devono essere utilizzate dai clienti - nella maggior parte dei casi, Component definisce una realizzazione di default che le sotto classi devono ridefinire Alcune di queste operazioni possono essere prive di significato per gli oggetti foglia (Add, Remove, )
48 Ingegneria del Software T - Design Pattern
Pattern COMPOSITE
Trasparenza
Dichiaro tutto al livello pi alto, in modo che il cliente possa trattare gli oggetti in modo uniforme ma il cliente potrebbe cercare di fare cose senza senso, come aggiungere figli alle foglie Se scegliamo la trasparenza
Add e Remove devono avere una realizzazione di default che genera uneccezione dovremmo disporre di un modo per verificare se possibile aggiungere figli alloggetto su cui si vuole agire
49
Pattern COMPOSITE
// Il cliente conosce solo Component Component parent = ComponentFactory.CreateInstance(); Component child = ComponentFactory.CreateInstance(); // Prima di inserire un figlio, // occorre controllare se possibile if(parent.IsComposite()) parent.Add(child);
50
Pattern COMPOSITE
Sicurezza
Tutte le operazioni sui figli vengono messe in Composite a questo punto, qualsiasi invocazione sulle foglie genera un errore in fase di compilazione ma il cliente deve conoscere e gestire due interfacce differenti Se scegliamo la sicurezza
dobbiamo disporre di un modo per verificare se loggetto su cui si vuole agire un Composite
51
Pattern COMPOSITE
// Il cliente conosce Component e Composite Component child = ComponentFactory.CreateComponent(); Composite parent1 = ComponentFactory.CreateComposite(); parent1.Add(child); Component parent2 = ComponentFactory.CreateComponent(); // Errore di compilazione parent2.Add(child); // Prima di inserire un figlio, // occorre controllare se possibile e fare un cast if(parent2 is Composite) ((Composite) parent2).Add(child);
52
Pattern VISITOR
Permette di definire una nuova operazione da effettuare su gli elementi di una struttura, senza dover modificare le classi degli elementi coinvolti Ad esempio, si consideri la rappresentazione di un programma come abstract syntax tree (AST) un albero i cui nodi descrivono elementi sintattici del programma Su tale albero devono poter essere effettuate molte operazioni di tipo diverso Controllare che tutte le variabili siano definite Eseguire delle ottimizzazioni Generare il codice macchina Stampare lalbero in un formato leggibile
53 Ingegneria del Software T - Design Pattern
Pattern VISITOR
Per lAST utilizziamo il pattern Composite
root Client 1 ComponentNode optimize() generateCode() print()
LeafNode
CompositeNode
54
Pattern VISITOR
In seguito potremmo voler effettuare altri tipi di operazioni controllare che le variabili siano state inizializzate prima delluso ristrutturare automaticamente il programma calcolare varie metriche Se distribuiamo le operazioni sui vari tipi di nodo, otteniamo un sistema che difficile da capire manutenere modificare
Ingegneria del Software T - Design Pattern
55
Pattern VISITOR
La soluzione quella di eliminare le singole operazioni dallAST (la cui responsabilit principale quella di rappresentare un programma sotto forma di albero) Tutto il codice relativo ad un singolo tipo di operazione (ad es. generazione del codice) viene raccolto in una singola classe I nodi dellAST devono accettare la visita delle istanze di queste nuove classi (visitor) Per aggiungere un nuovo tipo di operazione, sufficiente progettare una nuova classe
56
Pattern VISITOR
Il Visitor deve dichiarare unoperazione per ogni tipo di nodo concreto
NodeVisitor VisitVariable(in node : VariableNode) VisitConstant(in node : ConstantNode) VisitAssignment(in node : AssignmentNode)
CodeGeneratingVisitor VisitVariable(in node : VariableNode) VisitConstant(in node : ConstantNode) VisitAssignment(in node : AssignmentNode)
TypeCheckingVisitor VisitVariable(in node : VariableNode) VisitConstant(in node : ConstantNode) VisitAssignment(in node : AssignmentNode)
57
Pattern VISITOR
Ogni nodo deve dichiarare unoperazione per accettare un generico visitor
root Client 1 ComponentNode Accept(in v : NodeVisitor)
LeafNode
CompositeNode
v.VisitVariable(this)
v.VisitConstant(this)
v.VisitAssignment(this)
58
Pattern VISITOR
Visitor (classe astratta o interfaccia) Dichiara un metodo Visit per ogni classe di elementi concreti ConcreteVisitor Definisce tutti i metodi Visit Globalmente definisce loperazione da effettuare sulla struttura e (se necessario) ha un proprio stato
Visitor VisitConcreteElementA(in e : ConcreteElementA) VisitConcreteElementB(in e : ConcreteElementB)
59
Pattern VISITOR
Element (classe astratta o interfaccia) Dichiara un metodo Accept che accetta un Visitor come argomento ConcreteElement Definisce il metodo Accept
Element Accept(in v : Visitor)
ObjectStructure
v.VisitConcreteElementA(this)
v.VisitConcreteElementB(this)
60
Pattern VISITOR
ObjectStructure Pu essere realizzata come Composite o come normale collezione (array, lista, ) Deve poter enumerare i suoi elementi Deve dichiarare uninterfaccia che permetta a un cliente di far visitare la struttura a un Visitor
Client
Visitor
ObjectStructure
Element
61
Pattern VISITOR
Facilita laggiunta di nuove operazioni possibile aggiungere nuove operazioni su una struttura esistente, semplicemente aggiungendo un nuovo visitor concreto Senza il pattern Visitor, sarebbe necessario aggiungere un metodo ad ogni classe degli elementi della struttura Ogni Visitor concreto Raggruppa i metodi necessari ad eseguire una data operazione Nasconde i dettagli di come tale operazione debba essere eseguita
62
Pattern VISITOR
Incapsulamento Ogni Visitor deve essere in grado di accedere allo stato degli elementi su cui deve operare difficile aggiungere una nuova classe ConcreteElement Per ogni nuova classe ConcreteElement necessario inserire un nuovo metodo Visit in tutti i Visitor esistenti la gerarchia Element deve essere poco o per nulla modificabile cio essere stabile
63
Pattern VISITOR
Visita di elementi non correlati Non necessario che tutti gli elementi da visitare derivino da una classe comune VisitClasseA(ClasseGerarchiaA a); VisitClasseB(ClasseGerarchiaB b); Stato Durante loperazione ogni Visitor pu modificare il proprio stato ad esempio, per accumulare dei valori o altro
64
Pattern VISITOR
public class CompositeElement : Element { private List<Element> _children; public override void Accept(Visitor visitor) { foreach (Element aChild in _children) aChild.Accept(visitor); visitor.VisitCompositeElement(this); } }
65
Pattern VISITOR
: Client : ObjectStructure a : ConcreteElementA new() Accept(v) Accept(v) VisitConcreteElementA(a) OperazioneX() v : ConcreteVisitor1 b : ConcreteElementB
Accept(v)
66
Pattern VISITOR
Double dispatch
Loperazione che deve essere effettuata dipende dal tipo di due oggetti
il visitor lelemento
Esempio + EsempioDecorator
67
68
69
70
71
View
Controller
Model
Esempio
72 Ingegneria del Software T - Design Pattern
Tecnologia COM
Component Object Model 1993 COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact COM is not an object-oriented language but a standard COM specifies an object model and programming requirements that enable COM objects to interact with other objects
Tecnologia COM
Component Object Model
interface IUnknown { virtual HRESULT QueryInterface(IID iid, void **ppvObject) = 0; virtual ULONG AddRef(void) = 0; virtual ULONG Release(void) = 0; };
QueryInterface is used to obtain a pointer to another interface, given a GUID that uniquely identifies that interface (commonly known as an interface ID, or IID) if the COM object does not implement that interface, an E_NOINTERFACE error is returned instead AddRef is used by clients to indicate that a COM object is being referenced Release is used by clients to indicate that they have finished using the COM object
Tecnologia COM
Component Object Model
The COM specifications require a technique called reference counting to ensure that individual objects remain alive as long as there are clients which have acquired access to one or more of its interfaces and, conversely, that the same object is properly disposed of when all code that used the object have finished with it and no longer require it A COM object is responsible for freeing its own memory once its reference count drops to zero Reference counting may cause problems if two or more objects are circularly referenced
Tecnologia COM
Component Object Model Ereditariet solo con composizione e delega
interface IService2 : IService1
Ingegneria del Software T Ingegneria del Software T
5
ISe rvi ce1 Component2 Compone nt1
IService2
Tecnologia COM
Component Object Model
The location of each component is stored in the Windows registry There can be only one version of a certain component installed This limitation can seriously complicate the deployment of COM-based applications, due to the possibility that different programs, or even different versions of the same program, may be designed to work with different versions of the same COM component This condition is known as DLL hell
Framework .NET
un ambiente di esecuzione (runtime environment) 2002 v.1.0 Semplifica lo sviluppo e il deployment Aumenta laffidabilit del codice Unifica il modello di programmazione completamente indipendente da COM fortemente integrato con COM
Sviluppo semplificato
Ambiente object-oriented
Ingegneria del Software T Ingegneria del Software T
8
Qualsiasi entit un oggetto Classi ed ereditariet pienamente supportati Anche tra linguaggi diversi Linguaggi fortemente tipizzati Type Checker Errori non gestiti generazione di eccezioni Meno memory leak Garbage Collector
Common Language Infrastructure ECMA-334 (C#), ECMA-335 (CLI) SSCLI (Shared Source CLI by Microsoft, per Windows, FreeBSD e Macintosh) - Rotor Mono (per Linux) DotGNU Intel OCL (Open CLI Library)
Standard ECMA-335
Defines the Common Language Infrastructure (CLI) in which applications written in multiple high level languages may be executed in different system environments without the need to rewrite the application to take into consideration the unique characteristics of those environments CLI is a runtime environment, with:
10
a file format a common type system an extensible metadata system an intermediate language access to the underlying platform a factored base class library
Tutte le funzionalit del framework .NET sono disponibili a tutti i linguaggi .NET I componenti di unapplicazione possono essere scritti con diversi linguaggi Tool disponibili per tutti i linguaggi: Debugger, Profiler, ecc.
Framework .NET
Concetti chiave:
Ingegneria del Software T Ingegneria del Software T
12
Codice interpretato
Sorgenti
Interprete
Esecuzione
13
Codice nativo
Sorgenti
Compilatore
Esecuzione
Codice IL
Sorgenti
Ingegneria del Software T Ingegneria del Software T
Compilatore .NET
Codice IL (Assembly)
.EXE/.DLL
Compilatore JIT
Codice nativo
Esecuzione
15
Codice IL
Sorgenti
Ingegneria del Software T Ingegneria del Software T
Codice IL (Assembly)
.EXE/.DLL
Compilatore JIT
Codice nativo
Esecuzione
16
Codice IL
Sorgenti
Ingegneria del Software T Ingegneria del Software T
Codice IL (Assembly)
.EXE/.DLL
Compilatore JIT
Codice nativo
Esecuzione
17
Assembly
Unit minima per la distribuzione, il versioning e la security
1+ file Metadati che descrivono lassembly stesso Metadati che descrivono completamente tutti i tipi contenuti nellassembly Ottenuto da un qualsiasi linguaggio di programmazione Immagini, icone,
Manifest
Type metadata
Risorse
Assembly
Single-File Assembly
Type Metadata
IL Code
IL Code
IL Code
Pict.gif Resource
Resources
Assembly
.assembly Hello { } .assembly extern mscorlib { } .method public static void main() { .entrypoint ldstr "Hello IL World!" call void [mscorlib]System.Console::WriteLine (class System.String) ret }
ilasm helloil.il
Assembly
Assembly privati
Ingegneria del Software T Ingegneria del Software T
21
Utilizzati da unapplicazione specifica Directory applicazione (e sub-directory) Utilizzati da pi applicazioni Global Assembly Cache (GAC) c:\windows\assembly Download cache c:\windows\assembly\download Tool a linea di comando per esaminare GAC e download cache
Assembly condivisi
GACUTIL.EXE
Deployment semplificato
Installazione senza effetti collaterali
Esecuzione side-by-side
Diverse versioni dello stesso componente possono coesistere, anche nello stesso processo
Metadati
Descrizione dellassembly - Manifest
Ingegneria del Software T Ingegneria del Software T
23
Identit: nome, versione, cultura [, public key] Lista dei file che compongono lassembly Riferimenti ad altri assembly da cui si dipende Permessi necessari per lesecuzione Nome, visibilit, classe base, interfacce Campi, metodi, propriet, eventi, Definiti dal compilatore Definiti dal framework Definiti dallutente
Attributi
Ambienti RAD
Common Language Runtime (CLR) Funzionalit specifiche di CLR (es. Garbage Collector) Funzionalit esistenti (es. I/O su file) mediate da CLR
COM Marshaler Exception Manager Debug Engine Code Manager Garbage Collector (GC)
Class Loader
Sicurezza e affidabilit del codice Separazione spazi di memoria in un processo con AppDomain Controllo del codice e sicurezza dei tipi
Ingegneria del Software T Ingegneria del Software T
28
Cast non sicuri Variabili non inizializzate Accessi ad array oltre i limiti di allocazione
Garbage Collector
Garbage Collector per tutti gli oggetti .NET Gestione del ciclo di vita degli oggetti Gli oggetti vengono distrutti automaticamente quando non sono pi referenziati A differenza di COM, non ci si basa sul Reference Counting
Maggiore velocit di allocazione Consentiti i riferimenti circolari Perdita della distruzione deterministica
Algoritmo Mark-and-Compact
Garbage Collector e distruzione deterministica In alcuni casi serve un comportamento di finalizzazione deterministica
Riferimenti a oggetti non gestiti Utilizzo di risorse che devono essere rilasciate appena termina il loro utilizzo
Non possibile utilizzare il metodo Finalize (in C# il distruttore), in quanto non richiamabile direttamente necessario implementare linterfaccia IDisposable
In CLR, uneccezione un oggetto che eredita dalla classe System.Exception Gestione uniforme - elimina
Lanciare uneccezione (throw) Catturare uneccezione (catch) Eseguire codice di uscita da un blocco controllato (finally)
Analisi dei metadati di un assembly Generazione di un assembly dinamico Chiamata di componenti remoti (.NET)
Remoting
Reflection
possibile interrogare un assembly caricato in memoria
Tipi (classi, interfacce, enumeratori, etc.) Membri (attributi, propriet, metodi, etc.) Parametri
Consente di fornire un modello di programmazione unificato Progettato per linguaggi object-oriented, procedurali e funzionali
Esaminate caratteristiche di 20 linguaggi Tutte le funzionalit disponibili con IL Ogni linguaggio utilizza alcune caratteristiche Regole di compatibilit tra linguaggi Sottoinsieme di CTS
Overload di funzioni (compile-time) Invocazione metodi virtuali risolta a run-time Ereditariet singola di implementazione Ereditariet multipla di interfacce Gestione strutturata delle eccezioni
Regole di overload pi restrittive Nessun puntatore unmanaged Devono essere supportate interfacce multiple con metodi dello stesso nome Regole per costruttori degli oggetti Regole per denominazione propriet ed eventi
COBOL CLS
C++
C# object string bool char float double decimal sbyte byte short ushort int uint long ulong
System.Char System.Single System.Double System.Decimal System.SByte System.Byte System.Int16 System.UInt16 System.Int32 System.UInt32 System.Int64 System.UInt64
Tipi riferimento
Riferimenti a oggetti allocati sullheap gestito Indirizzi di memoria
Tipi valore
Allocati sullo stack o parte di altri oggetti Sequenza di byte
v.height v.width r
Stack
height width
Heap
Class CSize
_x
_y
v1
v2
_x
_y
Alla fine, rimangono 101 oggetti nellheap (1 array di Point + 100 Point)
Point[] points = new Point[100]; for (int i = 0; i < 100; i++) { points[i].X = i; points[i].Y = i; }
NO!
Object
String
Array
ValueType
EventArgs
Attribute
Exception
Delegate
struct DateTime
struct Enum
struct Double
struct Int32
struct Boolean
delegate MulticastDelegate
delegate EventHandler
Boxing / Unboxing
Un qualsiasi tipo valore pu essere automaticamente convertito in un tipo riferimento (boxing) mediante un up cast implicito a System.Object
Ingegneria del Software T Ingegneria del Software T
50
Un tipo valore boxed pu tornare ad essere un tipo valore standard (unboxing) mediante un down cast esplicito
int k = (int) o;
Boxing / Unboxing
int i = 123; object o = i; int k = (int) o;
Ingegneria del Software T Ingegneria del Software T
51
STACK
HEAP
i 123 o k 123
Int32 123
Modello di esecuzione
Source Code
Ingegneria del Software T Ingegneria del Software T
52
VB Compiler Assembly
C# Compiler Assembly
IL
Ngen
Native Code
Managed Code
Unmanaged Code
System.Data OleDb SqlClient Common SQLTypes System Collections Configuration Diagnostics Globalization IO Reflection Resources Security Text Threading Xsl XPath
Framework .NET
Il framework non una scatola nera E possibile estendere una qualsiasi classe .NET (non sealed) mediante ereditariet Diversamente da COM,
Ingegneria del Software T Ingegneria del Software T
54
si usa e si estende la classe stessa non si utilizza uno strato intermedio (wrapper)
Lereditariet cross-language
Bibliografia
Libri di base: D. S. Platt, Introducing Microsoft .NET, Second Edition (*) J. Sharp, J. Jagger, Microsoft Visual C# .NET Step by Step (*) T. Archer, A. Whitechapel, Inside C#, Second Edition (*) M. J. Young, XML Step by Step, Second Edition (*) R. M. Riordan, Microsoft ADO.NET Step by Step (*) Libri avanzati: J. Richter, Applied Microsoft .NET Framework Programming C. Petzold, Programming Microsoft Windows with C# (*) S. Lidin, Inside Microsoft .NET IL Assembler
(*) Disponibile nella biblioteca del DEIS
Tipi in .NET
Dal punto di vista del modo in cui le istanze vengono gestite in memoria (rappresentazione, tempo di vita, ), i tipi possono essere distinti in:
Dal punto di vista sintattico (sintassi del linguaggio C#), i tipi possono essere distinti in:
Classi class Interfacce interface Strutture struct Enumerativi enum Delegati delegate Array []
In .NET, si concretizzano sempre in una classe (anche nel caso di tipi built-in e di interfacce)
Tipi in .NET
In generale, un tipo pu contenere la definizione di 0+:
Costanti sempre implicitamente associate al tipo Campi (field) read-only o read-write, associati alle istanze o al tipo Metodi associati alle istanze o al tipo Costruttori di istanza o di tipo Operatori sempre associati al tipo Operatori di conversione sempre associati al tipo Propriet associate alle istanze o al tipo Indexer sempre associati alle istanze Eventi associati alle istanze o al tipo Tipi annidati
Modificatori di visibilit
Modificatore private
Ingegneria del Software T Ingegneria del Software T
4
Tipi annidati Visibile nel tipo contenitore (default) Visibile nel tipo contenitore e nei suoi sottotipi Visibile nellassembly contenitore
Visibile sia nel tipo contenitore e nei suoi sottotipi, sia nellassembly contenitore
protected
internal
protected internal
Non applicabile
public
Visibilit completa
Visibilit completa
Modificatori di visibilit
Modificatore private
Ingegneria del Software T Ingegneria del Software T
5
Dati default
Operazioni - Eventi Visibile nel tipo contenitore (default) Visibile nel tipo contenitore e nei suoi sottotipi Visibile nellassembly contenitore
Visibile sia nel tipo contenitore e nei suoi sottotipi, sia nellassembly contenitore
protected
Applicare esclusivamente a costanti ed eventualmente a campi read-only ( comunque preferibile laccesso mediante una propriet)
internal
protected internal
public
Visibilit completa
Modificatori di visibilit
Non sono applicabili nei seguenti casi:
Costruttori di tipo (statici) sempre inaccessibili invocati direttamente dal CLR Distruttori (finalizer) sempre inaccessibili invocati direttamente dal CLR Membri di interfacce sempre pubblici Membri di enum sempre pubblici Implementazione esplicita di membri di interfacce visibilit particolare (pubblici/privati), non modificabile Namespace sempre pubblici
Regole
Massimizzare lincapsulamento minimizzando la visibilit Information hiding a livello di assembly
Dichiarare public solo i tipi significativi dal punto di vista concettuale Dichiarare public solo metodi, propriet ed eventi significativi dal punto di vista concettuale Dichiarare protected solo le funzionalit che devono essere visibili nelle classi derivate, ma non esternamente ad esempio, costruttori particolari, metodi e propriet virtuali non public Field private e propriet public Field private e propriet protected
Costanti
Una costante un simbolo che identifica un valore che non pu cambiare Il tipo della costante pu essere solo un tipo considerato primitivo dal CLR (compreso string) Il valore deve essere determinabile compile-time Ad esempio, in Int32 esistono:
public const int MaxValue = 2147483647; public const int MinValue = -2147483648;
Si noti lutilizzo della maiuscola iniziale possibile applicare const anche alle variabili locali
Field
Un field un data member che pu contenere:
un valore (un istanza di un value type), oppure un riferimento (a unistanza di un reference type) in genere, la realizzazione di unassociazione di istanza (default), oppure di tipo (static) read-write (default), oppure read-only (readonly) inizializzato nella definizione o nel costruttore
Pu essere:
Pu essere:
Field
Qual la differenza tra le seguenti definizioni:
public const int MaxEntries = 100; public static readonly int MaxEntries = 100; Nel primo caso, la costante MaxEntries viene iniettata nel codice del cliente se il valore viene modificato e se il cliente e il fornitore sono in assembly diversi, necessario ricompilare anche il codice del cliente Nel secondo caso, laccesso al field MaxEntries quello standard: il valore in memoria ed necessario reperirlo se il valore viene modificato e se il cliente e il fornitore sono in assembly diversi, NON necessario ricompilare anche il codice del cliente
Ingegneria del Software T Ingegneria del Software T
10
Regole
Definire const solo le costanti vere, cio i valori veramente immutabili nel tempo (nelle versioni del programma), negli altri casi utilizzare field statici read-only il valore di MaxEntries non una costante vera perch in una versione successiva del programma potrebbe cambiare Costanti
il nome dovrebbe iniziare con una lettera maiuscola di solito, dovrebbe essere pubblica (ma non sempre cos) il nome deve iniziare con _ seguito da una lettera minuscola deve essere privata (accesso sempre mediante propriet) scegliere, a seconda delle situazioni, una delle due convenzioni precedenti
Field
Field read-only
Modificatori di metodi
virtual abstract override override sealed / sealed override Applicabili a:
Metodi Propriet (metodi get e set) Indexer (metodi get e set) Eventi (metodi add e remove)
By default, methods are non-virtual It is an error to use the virtual modifier on a static method
protected virtual void Method() { } public virtual int Property { get { } set { } } public virtual int this[int index] { get { } }
An abstract method is implicitly a virtual method Abstract method declarations are only permitted in abstract classes
The implementation is provided by an overriding method It is an error to use the static or virtual modifiers in an abstract method declaration
protected abstract void Method(); public abstract int Property { get; set; } public abstract int this[int index] { get; }
Must be virtual, abstract, or override Must have the same signature as the override method
You cannot override a non-virtual or static method An override declaration cannot change the accessibility of the overridden base method Use of the sealed modifier prevents a derived class from further overriding the method
protected override void Method() { } public override sealed int Property { get { } set { } } public override int this[int index] { get { } }
Metodi
Passaggio degli argomenti
Tre tipi di argomenti:
In (default in C#)
Largomento deve essere inizializzato Largomento viene passato per valore (per copia) Eventuali modifiche del valore dellargomento non hanno effetto sul chiamante
Metodi
Passaggio degli argomenti In
Value type
Viene passata una copia delloggetto Eventuali modifiche vengono effettuate sulla copia e non hanno alcun effetto sulloggetto originale Viene passata una copia del riferimento alloggetto Eventuali modifiche delloggetto referenziato hanno effetto Eventuali modifiche del riferimento vengono effettuate sulla copia e non hanno alcun effetto sul riferimento originale
Reference type
Point p1 = new Point(0,0); Method1(p1); Console.WriteLine("{0}",p1); static void Method1(Point p) { p.X = 100; p.Y = 100; }
Metodi
Passaggio degli argomenti In/Out
Value type
Viene passato lindirizzo delloggetto Eventuali modifiche agiscono direttamente sulloggetto originale Viene passato lindirizzo del riferimento alloggetto Eventuali modifiche delloggetto referenziato hanno effetto Eventuali modifiche del riferimento agiscono direttamente sul riferimento originale
Reference type
Point p1 = new Point(0,0); Method2(ref p1); Console.WriteLine("{0}",p1); static void Method2(ref Point p) { p.X = 100; p.Y = 100; }
Metodi
Passaggio degli argomenti
class/struct Persona Persona p1 = new Persona(Tizio); Method1(p1); // p1 == Tizio Method2(ref p1); // p1 == Sempronio static void Method1(Persona p) { p = new Persona(Caio); // }
//
p1 == Tizio
p == Caio
p == Sempronio
Metodi
Passaggio degli argomenti Out
Value type e Reference type
Viene passato lindirizzo delloggetto o del riferimento alloggetto come nel caso In/Out Non necessario che loggetto o il riferimento siano inizializzati prima di essere passati come argomento Loggetto o il riferimento DEVONO essere inizializzati nel metodo a cui sono stati passati come argomento
Point p1; Method3(out p1); static void Method3(out Point p) { // In questo punto il compilatore suppone che // p NON sia inizializzato p.X = 100; p.Y = 100; // Non compila! p = new Point(100,100); // indispensabile }
Regole
Utilizzare prevalentemente il passaggio standard per valore Utilizzare il passaggio per riferimento (ref o out) solo se strettamente necessario
2+ valori da restituire al chiamante 1+ valori da utilizzare e modificare nel metodo Scegliere ref se loggetto passato come argomento deve essere gi stato inizializzato Scegliere out se responsabilit del metodo inizializzare completamente loggetto passato come argomento
void Swap(ref int value1, ref int value2) { } void SplitCognomeNome(string cognomeNome, out string cognome, out string nome) { }
Metodi
Numero variabile di argomenti
Si supponga di dover scrivere:
Add(a,b); // a+b Add(10,20,30); // 10+20+30 Add(x1,x2,x3,x4); // x1+x2+x3+x4
Ingegneria del Software T Ingegneria del Software T
22
Soluzioni possibili:
Overloading del metodo Add Svantaggio: posso solo codificare un numero finito di metodi Definire un solo metodo Add che accetti un numero variabile di argomenti
int Add(params int[] operands) { int total = 0; foreach (int operand in operands) total += operand; return total; }
Metodi
Numero variabile di argomenti
Non solo posso scrivere:
Add(a,b); Add(10,20,30); Add(x1,x2,x3,x4);
Ingegneria del Software T Ingegneria del Software T
23
Ma anche:
Add(); // restituisce 0 int[] numbers = { 10,20,30,40,50 }; Add(numbers); Add(new int[] { 10,20,30,40,50 }); Add(new int[] { x1,x2,x3,x4,x5 });
Zucchero sintattico:
Add(x1,x2,x3,x4); Add(new int[] { x1,x2,x3,x4 });
Costruttori di istanza
Responsabilit: inizializzare correttamente lo stato delloggetto appena creato (nulla di pi!) In mancanza di altri costruttori, esiste sempre un costruttore di default senza argomenti che, semplicemente, invoca il costruttore senza argomenti della classe base Nel caso delle classi, il costruttore senza argomenti pu essere definito dallutente Nel caso delle strutture, il costruttore senza argomenti NON pu essere definito dallutente (per motivi di efficienza) In entrambi i casi, possibile definire altri costruttori con differente signature e differente visibilit
Ingegneria del Software T Ingegneria del Software T
24
Costruttori di istanza
public abstract class DataAdapterManager { private readonly IDataTable _dataTable; private readonly IConnectionManager _connectionManager;
Ingegneria del Software T Ingegneria del Software T
protected DataAdapterManager(IDataTable dataTable, IConnectionManager connectionManager) { if(dataTable == null) throw new ArgumentNullException("dataTable"); if(connectionManager == null) throw new ArgumentNullException("connectionManager"); _dataTable = dataTable; _connectionManager = connectionManager; } }
25
Costruttori di istanza
public class XmlDataAdapterManager : DataAdapterManager { private readonly Encoding _encoding; public XmlDataAdapterManager(IDataTable dataTable, XmlConnectionManager xmlConnectionManager) : this(dataTable, xmlConnectionManager, Encoding.Unicode) { } public XmlDataAdapterManager(IDataTable dataTable, XmlConnectionManager xmlConnectionManager, Encoding encoding) : base(dataTable, xmlConnectionManager) { _encoding = encoding; } }
26
Costruttori di tipo
Responsabilit: inizializzare correttamente lo stato comune a tutte le istanze della classe field statici Dichiarato static Implicitamente private Sempre senza argomenti no overloading Pu accedere esclusivamente ai membri (field, metodi, ) statici della classe Se esiste, viene invocato automaticamente dal CLR
Prima della creazione della prima istanza della classe Prima dellinvocazione di un qualsiasi metodo statico della classe
Costruttori di tipo
class MyType { static int _x = 5; } class MyType { static int _x; static MyType() { _x = 5; } } class MyType { static int _x = 5; static MyType() { _x = 10; } } Viene definito implicitamente un costruttore di tipo
Regole
Definire un costruttore di tipo solo se strettamente necessario, cio se i campi statici della classe
NON possono essere inizializzati in linea Devono essere inizializzati solo se la classe viene effettivamente utilizzata
public class A { private static XmlDocument _xmlDocument; static A() { _xmlDocument = new XmlDocument(); _xmlDocument.Load(); } }
Costruttori ed eccezioni
Supponiamo che
Ingegneria del Software T Ingegneria del Software T
30
un costruttore lanci uneccezione e leccezione non venga gestita allinterno del costruttore stesso (quindi arrivi al chiamante)
Interfacce
In C#, uninterfaccia pu contenere esclusivamente:
Metodi considerati pubblici e astratti Propriet considerate pubbliche e astratte Indexer considerati pubblici e astratti Eventi considerati pubblici e astratti
In CLR, uninterfaccia considerata una particolare classe astratta di sistema che (ovviamente) non deriva da System.Object per, le classi che la implementano derivano per forza da System.Object Uninterfaccia
Pu essere implementata sia dai reference type, sia dai value type considerata sempre un reference type Attenzione: se si effettua il cast di un value type a uninterfaccia, avviene un boxing del value type (con conseguente copia del valore)!
//
virtual sealed
public class MyClass : IMyInterface1, IMyInterface2 { void IMyInterface1.Close() { } void IMyInterface2.Close() { } public void Close() { } } MyClass a = new MyClass(); ((IMyInterface1) a).Close(); ((IMyInterface2) a).Close(); a.Close(); // Ok!
// //
Ok! Ok!
Framework .NET
Object
String
Array
ValueType
EventArgs
Attribute
Exception
Delegate
struct DateTime
struct Enum
struct Double
struct Int32
struct Boolean
delegate MulticastDelegate
delegate EventHandler
System.Object
Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes This is the ultimate superclass of all classes in the .NET Framework; it is the root of the type hierarchy Because all classes in the .NET Framework are derived from Object, every method defined in the Object class is available in all objects in the system
System.Object
Object + Object ( ) # Finalize ( ) + GetHashCode ( ) : System.Int32 + Equals ( [in] obj : System.Object ) : System.Boolean + ToString ( ) : System.String + Equals ( [in] objA : System.Object , [in] objB : System.Object ) : System.Boolean + ReferenceEquals ( [in] objA : System.Object , [in] objB : System.Object ) : System.Boolean + GetType ( ) : System.Type # MemberwiseClone ( ) : System.Object
System.Object
Derived classes can and do override some of these methods, including: Equals - Supports comparisons between objects ToString - Manufactures a human-readable text string that describes an instance of the class GetHashCode - Generates a number corresponding to the value of the object to support the use of a hash table Finalize - Performs cleanup operations before an object is automatically reclaimed
Object.Equals
public virtual bool Equals(object obj); Return value: true if this is equal to obj otherwise, false The default implementation of Equals supports reference equality only, but derived classes can override this method to support value equality For reference types, equality is defined as object equality; that is, whether the references refer to the same object For value types, equality is defined as bitwise equality The ValueType class supports value types
Object.Equals
The following statements must be true for all implementations of the Equals method. In the list, x, y, and z represent object references that are not a null reference
x.Equals(x) returns true x.Equals(y) returns the same value as y.Equals(x) x.Equals(y) returns true if both x and y are NaN (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true Successive calls to x.Equals(y) return the same value as long as the objects referenced by x and y are not modified x.Equals(a null reference) returns false
Object.Equals
For some kinds of objects, it is desirable to have Equals test for value equality instead of referential equality Such implementations of Equals return true if the two objects have the same value, even if they are not the same instance The types implementer decides what constitutes an objects value, but it is typically some or all the data stored in the instance variables of the object For example, the value of a String is based on the characters of the string; the Equals method of the String class returns true for any two string instances that contain exactly the same characters in the same order
Object.Equals
Types that override Equals must also override GetHashCode; otherwise, Hashtable might not work correctly If your programming language supports operator overloading and if you choose to overload the equality operator for a given type, that type should override the Equals method Such implementations of the Equals method should return the same results as the equality operator
Object.Equals
public class Point { private readonly int x, y; public override bool Equals(object obj) { //Check for null and compare run-time types. if(obj == null || GetType() != obj.GetType()) return false; Point p = (Point) obj; return (x == p.x) && (y == p.y); } public override int GetHashCode() { return x ^ y; } }
Object.Equals
public class SpecialPoint : Point { private readonly int w; public SpecialPoint(int x, int y, int w) : base(x, y) { this.w = w; } public override bool Equals(object obj) { return base.Equals(obj) && w == ((SpecialPoint) obj).w; } public override int GetHashCode() { return base.GetHashCode() ^ w; } }
Object.Equals
public class Rectangle { private readonly Point a, b; public override bool Equals(object obj) { if(obj == null || GetType() != obj.GetType()) return false; Rectangle r = (Rectangle) obj; // Uses Equals to compare variables. return a.Equals(r.a) && b.Equals(r.b); } public override int GetHashCode() { return a.GetHashCode() ^ b.GetHashCode(); } }
Object.Equals
public struct Complex { private readonly double re, im; public override bool Equals(object obj) { return obj is Complex && this == (Complex) obj; } public override int GetHashCode() { return re.GetHashCode() ^ im.GetHashCode(); } public static bool operator ==(Complex x, Complex y) { return x.re == y.re && x.im == y.im; } public static bool operator !=(Complex x, Complex y) { return !(x == y); } }
System.ValueType
Object
ValueType
# ValueType ( ) + GetHashCode ( ) : System.Int32 + Equals ( [in] obj : System.Object ) : System.Boolean + ToString ( ) : System.String
One or more fields of the derived type is used to calculate the return value. If one or more of those fields contains a mutable value, the return value might be unpredictable, and unsuitable for use as a key in a hash table. In that case, consider writing your own implementation of GetHash Code that more closely represents the concept of a hash code for the type.
The default implementation of the Equals method uses reflection to compare the corresponding fields of obj and this instance. Override the Equals method for a particular type to improve the performance of the method and more closely represent the concept of equality for the type.
System.Boolean
interface IComparable
ValueType
interface IConvertible
struct Boolean + TrueString : System.String + FalseString : System.String + ToString ( [in] provider : System.IFormatProvider ) : System.String + GetTypeCode ( ) : System.TypeCode + CompareTo ( [in] obj : System.Object ) : System.Int32 + GetHashCode ( ) : System.Int32 + Equals ( [in] obj : System.Object ) : System.Boolean + ToString ( ) : System.String + Parse ( [in] value : System.String ) : System.Boolean
+ ToType ( ) + ToString ( ) + ToDateTime ( ) + ToDecimal ( ) + ToDouble ( ) + ToSingle ( ) + ToUInt64 ( ) + ToInt64 ( ) + ToUInt32 ( ) + ToInt32 ( ) + ToUInt16 ( ) + ToInt16 ( ) + ToByte ( ) + ToSByte ( ) + ToChar ( ) + ToBoolean ( ) + GetTypeCode ( )
System.Int32
interface IFormattable
ValueType
struct Int32
+ ToString ( [in] provider : System.IFormatProvider ) : System.String + GetTypeCode ( ) : System.TypeCode + ToString ( [in] format : System.String , [in] provider : System.IFormatProvider ) : System.String + CompareTo ( [in] value : System.Object ) : System.Int32 + GetHashCode ( ) : System.Int32 + Equals ( [in] obj : System.Object ) : System.Boolean + ToString ( ) : System.String + ToString ( [in] format : System.String ) : System.String + Parse ( [in] s : System.String ) : System.Int32 + Parse ( [in] s : System.String , [in] style : System.Globalization.NumberStyles ) : System.Int32 + Parse ( [in] s : System.String , [in] provider : System.IFormatProvider ) : System.Int32 + Parse ( [in] s : System.String , [in] style : System.Globalization.NumberStyles , [in] provider : Sys...
System.IComparable
interface IComparable
Compares the current instance with another object of the same type Return Value: a 32-bit signed integer that indicates the relative order of the comparands The return value has these meanings:
Less than zero - this instance is less than obj Zero - this instance is equal to obj Greater than zero - this instance is greater than obj
By definition, any object compares greater than a null reference The parameter obj must be the same type as the class or value type that implements this interface; otherwise, an ArgumentException is thrown
System.IComparable
Notes to Implementers: For any objects A, B and C, the following must be true:
A.CompareTo(A) is required to return zero If A.CompareTo(B) returns zero then B.CompareTo(A) is required to return zero If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero then A.CompareTo(C) is required to return zero If A.CompareTo(B) returns a value other than zero then B.CompareTo(A) is required to return a value of the opposite sign If A.CompareTo(B) returns a value x not equal to zero, and B.CompareTo(C) returns a value y of the same sign as x, then A.CompareTo(C) is required to return a value of the same sign as x and y
Esempio 1
System.IComparable
Se volessi:
Ingegneria del Software T Ingegneria del Software T
19
System.Collections.IComparer
interface IComparer
This interface is used in conjunction with the Array.Sort and Array.BinarySearch methods It provides a way to customize the sort order of a collection
IComparable IComparer
struct Point + property X : int + property Y : int - _x : int - _y : int + Point ( ) + ToString ( ) + CompareTo ( ) use
Comparer - _up : bool = true + Comparer ( ) + Comparer ( [in] up : bool ) + Compare ( [in] obj1 : object , [in] obj2 : object ) : int
Esempio 1
System.IConvertible
interface IConvertible
+ ToType ( ) + ToString ( ) + ToDateTime ( ) + ToDecimal ( ) + ToDouble ( ) + ToSingle ( ) + ToUInt64 ( ) + ToInt64 ( ) + ToUInt32 ( ) + ToInt32 ( ) + ToUInt16 ( ) + ToInt16 ( ) + ToByte ( ) + ToSByte ( ) + ToChar ( ) + ToBoolean ( ) + GetTypeCode ( )
This interface provides methods to convert the value of an instance of an implementing type to a common language runtime type that has an equivalent value The common language runtime types are Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String If there is no meaningful conversion to a common language runtime type, then a particular interface method implementation throws InvalidCastException - For example, if this interface is implemented on a Boolean type, the implementation of the ToDateTime method throws an exception because there is no meaningful DateTime equivalent to a Boolean type
System.Convert
Convert + DBNull : System.Object + GetTypeCode ( ) + IsDBNull ( ) + ChangeType ( ) + ToBoolean ( ) + ToChar ( ) + ToSingle ( ) + ToDouble ( ) + ToDecimal ( ) + ToDateTime ( ) + ToByte ( ) + ToSByte ( ) + ToInt16 ( ) + ToUInt16 ( ) + ToInt32 ( ) + ToUInt32 ( ) + ToInt64 ( ) + ToUInt64 ( ) + ToString ( ) + ToBase64String ( ) + ToBase64String ( ) + FromBase64String ( ) + ToBase64CharArray ( ) + FromBase64CharArray ( )
necessario scrivere:
((IConvertible) x).ToDouble()
System.Convert
Throws an exception if the conversion is not supported
bool b = Convert.ToBoolean(DateTime.Today); // InvalidCastException
OverflowException
Is also useful if you have a string that you want to convert to a numeric value:
string myString = "123456789"; int myInt = Convert.ToInt32(myString);
Conversione di tipo
Widening conversion occurs when a value of one type is converted to another type that is of equal or greater size
Da Int32 a Int64 Da Int32 a UInt64 Da Int32 a Single (con possibile perdita di precisione) Da Int32 a Double
Narrowing conversion occurs when a value of one type is converted to a value of another type that is of a smaller size
Da Int32 a Byte Da Int32 a SByte Da Int32 a Int16 Da Int32 a UInt16 Da Int32 a UInt32
Conversione di tipo
Conversioni implicite non generano eccezioni
Conversioni numeriche Il tipo di destinazione dovrebbe essere in grado di contenere, senza perdita di informazione, tutti i valori ammessi dal tipo di partenza Eccezione:
int k1 = 1234567891; float b = k1; int k2 = (int) b; //
k2 == 1234567936
Up cast Principio di sostituibilit: deve sempre essere possibile utilizzare una classe derivata al posto della classe base
B b = new B(); A a = b; // class B : A
Conversione di tipo
Conversioni esplicite possono generare eccezioni
Conversioni numeriche Il tipo di destinazione non sempre in grado di contenere il valore del tipo di partenza
int k1 = -1234567891; uint k2 = (uint) k1; // k2 == 3060399405
//
OverflowException
// OverflowException
Conversione di tipo
Conversioni esplicite possono generare eccezioni
Down cast
A a = new B(); // class B : A B b = (B) a; // Ok
InvalidCastException
if(a is B) // if(a.GetType() == typeof(B)) { b = (B) a; // Non genera eccezioni } b = a as B; // if(b != null) { } b = (a is B) ? (B) a : null;
Conversione di tipo
Boxing up cast (conversione implicita)
int k1 = 100; object o = k1; k1 = 200; // Copia!
Esempio 1 - Digit
Conversioni a string
Conversioni a string (di un Int32): ToString()
int k1 = -1234567891; string str = k1.ToString(); // str == -1234567891
ToString(string formatString)
the instance is formatted with the NumberFormatInfo for the current culture k1.ToString(X); // = B669FD2D k1.ToString(C); // = - 1.234.567.891,00 k1.ToString(C0); // = - 1.234.567.891 k1.ToString(N0); // = -1.234.567.891 k1.ToString(E); // = -1,234568E+009
Conversioni a string
Conversioni a string (di un Int32):
String.Format(string format, params object[] args) The format parameter is embedded with zero or more format items of the form, {index[,alignment][:formatString]} int k1 = -1234567891; String.Format({0},k1); // = -1234567891 String.Format({0:X},k1); // = B669FD2D String.Format({0,5:X},k1); // = B669FD2D String.Format({0,10:X},k1); // = B669FD2D String.Format({0,-10:X},k1); // = B669FD2D String.Format({0:N0},k1); // = -1.234.567.891
Conversioni da string
Conversioni da string (in un Int32): Int32.Parse(string str)
Int32.Parse(-1234567891); // -1234567891 Int32.Parse(-1.234.567.891); // FormatException Int32.Parse(); // FormatException Int32.Parse(-1234567891999); // OverflowException Int32.Parse(null); // ArgumentNullException
Int32.Parse(string str, System.Globalization.NumberStyles style) NumberStyles determines the styles permitted in numeric string arguments that are passed to the Parse methods of the numeric base type classes
Conversioni da string
enumeration NumberStyles None = 0 AllowLeadingWhite = 1 AllowTrailingWhite = 2 AllowLeadingSign = 4 AllowTrailingSign = 8 AllowParentheses = 16 AllowDecimalPoint = 32 AllowThousands = 64 AllowExponent = 128 AllowCurrencySymbol = 256 AllowHexSpecifier = 512 Integer = 7 HexNumber = 515 Number = 111 Float = 167 Currency = 383 Any = 511
The symbols to use for currency symbol, thousands separator, decimal point indicator, and leading sign are specified by NumberFormatInfo The attributes of NumberStyles are set by using the bitwise inclusive OR of the field flags
Conversioni da string (in un Int32): Convert.ToInt32(string str, int fromBase) fromBase = 2, 8, 10, 16
Convert.ToInt32(-1234567891); // -1234567891 Convert.ToInt32(-1234567891,10); // -1234567891 Convert.ToInt32(B669FD2D,16); // -1234567891 Convert.ToInt32(0xB669FD2D,16); // -1234567891 Convert.ToInt32(B669FD2D,10); // FormatException
TECNICHE AVANZATE
System.IFormattable
interface IFormattable
+ Format ( [in] format : System.String , [in] arg : System.Object , [in] formatProvider : System.IFormatProvider ) : System.String
Defines a method that supports custom, user-defined formatting of the value of an object
System.Double
ValueType
IComparable
struct Double + MinValue : System.Double + MaxValue : System.Double + Epsilon : System.Double + NegativeInfinity : System.Double + PositiveInfinity : System.Double + NaN : System.Double + ToString ( ) + GetTypeCode ( ) + ToString ( ) + CompareTo ( ) + GetHashCode ( ) + Equals ( ) + ToString ( ) + IsInfinity ( ) + IsPositiveInfinity ( ) + IsNegativeInfinity ( ) + IsNaN ( ) + ToString ( ) + Parse ( ) + Parse ( ) + Parse ( ) + Parse ( ) + TryParse ( )
Follows IEEE 754 specification Supports 0, Infinity, NaN Epsilon represents the smallest positive Double > 0 The TryParse method is like the Parse method, except this method does not throw an exception if the conversion fails
IConvertible IFormattable
If the conversion succeeds, the return value is true and the result parameter is set to the outcome of the conversion If the conversion fails, the return value is false and the result parameter is set to zero
System.Enum
ValueType
struct Enum IComparable IConvertible IFormattable # Enum ( ) + ToString ( ) + GetTypeCode ( ) + CompareTo ( ) + GetHashCode ( ) + Equals ( ) + Parse ( ) + GetUnderlyingType ( ) + GetValues ( ) + GetName ( ) + GetNames ( ) + IsDefined ( ) + Format ( ) + ToObject ( )
Compare instances of this class Convert the value of an instance to its string representation Convert the string representation of a number to an instance of this class Create an instance of a specified enumeration and value
Esempio 1 - Color
System.DateTime
ValueType
struct DateTime + MinValue : System.DateTime + MaxValue : System.DateTime + property Date : System.DateTime + property Day : System.Int32 + property DayOfWeek : System.DayOfWeek + property DayOfYear : System.Int32 + property Hour : System.Int32 + property Millisecond : System.Int32 + property Minute : System.Int32 + property Month : System.Int32 + property Now : System.DateTime + property UtcNow : System.DateTime + property Second : System.Int32 + property Ticks : System.Int64 + property TimeOfDay : System.TimeSpan + property Today : System.DateTime + property Year : System.Int32
Represents an instant in time, typically expressed as a date and time of day The DateTime value type represents dates and times with values ranging from 12:00:00 midnight, January 1, 0001 Anno Domini (Common Era) to 11:59:59 P.M., December 31, 9999 A.D. (C.E.) Time values are measured in 100ns units called ticks DateTime represents an instant in time, whereas a TimeSpan represents a time interval
System.String
interface IEnumerable Object interface ICloneable
+ GetEnumerator ( ) : System.Collections.IEnumerator
+ Clone ( ) : System.Object
IComparable
IConvertible
An immutable, fixed-length string of Unicode characters A String is called immutable because its value cannot be modified once it has been created Methods that appear to modify a String actually return a new String containing the modification If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class
Esempio 1
System.ICloneable
interface ICloneable
+ Clone ( ) : System.Object
Supports cloning, which creates a new instance of a class with the same value as an existing instance
Clone creates a new object that is a copy of the current instance Clone can be implemented either as
a shallow copy, only the top-level objects are duplicated, no new instances of any fields are created public object Clone() { return MemberwiseClone(); }
Clone returns a new instance that is of the same type as (or occasionally a derived type of) the current object
System.Collections.IEnumerable
Exposes the enumerator, which supports a simple iteration over a collection
interface IEnumerable
+ GetEnumerator ( ) : System.Collections.IEnumerator
Enumerators only allow reading the data in the collection Enumerators cannot be used to modify the underlying collection
Reset returns the enumerator to its initial state MoveNext moves to the next item in the collection, returning true if the operation was successful false if the enumerator has moved past the last item Current returns the object to which the enumerator currently refers
System.Collections.IEnumerator
Non deve essere implementata direttamente da una classe contenitore Deve essere implementata da una classe separata (eventualmente annidata nella classe contenitore) che fornisce la funzionalit di iterare sulla classe contenitore Tale suddivisione di responsabilit permette di utilizzare contemporaneamente pi enumeratori sulla stessa classe contenitore La classe contenitore deve implementare linterfaccia IEnumerable Se una classe contenitore viene modificata, tutti gli enumeratori ad essa associati vengono invalidati e non possono pi essere utilizzati (InvalidOperationException)
System.Collections.IEnumerator
System.Collections.IEnumerator
public class Contenitore : IEnumerable { public IEnumerator GetEnumerator() { return new Enumeratore(this); } class Enumeratore : IEnumerator { public Enumeratore(Contenitore contenitore) } }
Esempio 1 - Contenitore
System.Array
IC lo n e a b le O b je c t IE n u m e ra b le
A rra y
+ + + + + + + + + + + + + + + + + + + + + + + + + p rop e rty p rop e rty p rop e rty p rop e rty p rop e rty p rop e rty Le ngt h : Sys te m .Int 32 R a nk : Sys t e m .Int3 2 Sync R o o t : Sys t e m .O b je c t Is R e a d O nly : Sys te m .B o ole a n Is F ixe d Siz e : Sys te m .B oo le a n Is Sync hro niz e d : Sys t e m .B o o le a n )
int e rfa c e IC o lle c tio n + p ro pe rty C o unt : Sys t e m .Int3 2 + p ro pe rty Sync R oo t : Sys te m .O b je c t + p ro pe rty Is Sync hro niz e d : Sys t e m .B o o le a n
+ C o pyT o ( )
G e t E num e ra to r ( C o p yT o ( ) C lo ne ( ) C re a t e Ins ta nc e ( C le a r ( ) G e t V a lue ( ) Se tV a lue ( ) G e t Le ng th ( ) G e t U pp e rB ound ( G e t Lo w e rB ound ( B ina rySe a rc h ( ) Inde xO f ( ) La s tInd e xO f ( ) R e ve rs e ( ) So rt ( ) Init ia liz e ( ) C o p yT o ( ) C re a t e Ins ta nc e ( Copy ( )
int e rfa c e IL is t + p ro pe rty Ite m ( Sys te m .Int 32 ) : Sys te m .O b je c t + p ro pe rty Is R e a d O nly : Sys te m .B o o le a n + p ro pe rty Is F ixe d Siz e : Sys te m .B o ole a n
) )
+ + + + + + +
( ) ) ) )
System.Array
One-dimensional arrays
int[] a = new int[3]; int[] b = new int[] {3, 4, 5}; int[] c = {3, 4, 5}; // array of references SomeClass[] d = new SomeClass[10]; // array of values (directly in the array) SomeStruct[] e = new SomeStruct[10];
Ingegneria del Software T Ingegneria del Software T
46
System.Array
Multidimensional arrays (jagged)
// array of references to other arrays int[][] a = new int[2][]; // cannot be initialized directly a[0] = new int[] {1, 2, 3}; a[1] = new int[] {4, 5, 6};
Ingegneria del Software T Ingegneria del Software T
47
System.Array
Jagged (like in Java)
int[][] a = new int[2][]; a[0] = new int[3]; a[1] = new int[4]; int x = a[0][1];
a[0][1] a a[0] a[1]
Delegati ed Eventi
Delegati
Sono oggetti che possono contenere il riferimento (type safe) a un metodo, tramite il quale il metodo pu essere invocato Oggetti funzione (functor) oggetti che si comportano come una funzione (metodo) Simili ai puntatori a funzione del C/C++, ma object-oriented e molto pi potenti Utilizzo standard: funzionalit di callback
Elaborazione asincrona Elaborazione cooperativa (il chiamato fornisce una parte del servizio, il chiamante fornisce la parte rimanente es. qsort in C) Gestione degli eventi (chi interessato a un certo evento si registra presso il generatore dellevento, specificando il metodo che gestir levento)
int funX(char c); int funY(char c); int (*g)(char c) = NULL; ... g = cond1 ? funX : funY; oppure: g = cond1 ? &funX : &funY; ... g('H') (*g)('H')
void fun0(char *s); void fun1(char *s); void fun2(char *s); void (*fun[])(char *s) = { fun0, fun1, fun2 }; ... fun[m]("stringa di caratteri"); (*fun[m])("stringa di caratteri");
fun0 fun[0] fun[1] fun[2] fun2 fun1
Delegati
Dichiarazione di un nuovo tipo di delegato che pu contenere il riferimento a un metodo che ha un unico argomento intero e restituisce un intero:
delegate int Action(int param);
Ingegneria del Software T Ingegneria del Software T
5
Definizione di un delegato:
Action action;
Inizializzazione di un delegato:
action = new Action(nomeMetodoStatico); action = new Action(obj.nomeMetodo);
Delegati
Esempio
delegate int Action(int param); class Class1 { static void Main(string[] args) { Action action; action = new Action(Raddoppia); Console.WriteLine("Risultato: {0}", action(10)); action = new Action(Dimezza); Console.WriteLine("Risultato: {0}", action(10)); } static int Raddoppia(int x) { return x * 2; } static int Dimezza(int x) Risultato: 20 { return x / 2; } } Risultato: 5
Delegati
Esempio
delegate int Action(int param); class Class1 { static void Main(string[] args) { Go(new Action(Raddoppia)); Go(new Action(Dimezza)); } static void Go(Action action) { Console.WriteLine("Risultato: {0}", action(10)); } static int Raddoppia(int x) { return x * 2; } static int Dimezza(int x) Risultato: 20 { return x / 2; } } Risultato: 5
Delegati
Esempio
Un delegato pu contenere anche il riferimento a un metodo NON statico in questo caso mantiene un riferimento anche alloggetto su cui invocare il metodo
Ingegneria del Software T Ingegneria del Software T
8
delegate int Action(int param); class Class1 { private int _y; public Class1(int y) { _y = y; } public int Moltiplica(int x) { return x * _y; } public int Dividi(int x) { return x / _y; } }
Delegati
Esempio
static void Main(string[] args) { Action action; Class1 c = new Class1(5); action = new Action(Raddoppia); Console.WriteLine("Risultato: {0}", action = new Action(Dimezza); Console.WriteLine("Risultato: {0}", action = new Action(c.Moltiplica); Console.WriteLine("Risultato: {0}", action = new Action(c.Dividi); Console.WriteLine("Risultato: {0}", }
20 5 50 2
Delegati
Esempio3.Step1
Ingegneria del Software T Ingegneria del Software T
10
Esempio3.Step2
Delegati
Multicasting
Possibilit di creare una lista di metodi che vengono chiamati automaticamente e in sequenza allatto della chiamata del delegato Per aggiungere un metodo alla lista: +=
Action action = new Action(Fun1); action(10) // Fun1(10) action += new Action(Fun2); action(10) // Fun1(10), Fun2(10)
Delegati
Invocation of a delegate instance whose invocation list contains multiple entries proceeds by invoking each of the methods on the invocation list, synchronously, in order Each method so called is passed the same set of arguments as was given to the delegate instance If such a delegate invocation includes reference parameters
each method invocation will occur with a reference to the same variable changes to that variable by one method in the invocation list will be visible to methods further down the invocation list
their final value will come from the invocation of the last delegate in the list
Delegati
Esempio multicasting
delegate string Action(ref string param); class Class1 { static string ToUpper(ref string str) { str = str.ToUpper(); return str; } static string TrimEnd(ref string str) { str = str.TrimEnd(); return str; } static string TrimStart(ref string str) { str = str.TrimStart(); return str; }
Delegati
Esempio multicasting
static void Main(string[] args) { string s1 = " abcdefghijk "; Action action = new Action(ToUpper) + new Action(TrimStart) + new Action(TrimEnd); Console.WriteLine("s1a: \"" + action(ref s1) + "\""); Console.WriteLine("s1b: \"" + s1 + "\""); } }
Delegati
A delegate instance encapsulates one or more methods (with a particular set of arguments and return type), each of which is referred to as a callable entity For static methods, a callable entity consists of just a method For instance methods, a callable entity consists of an instance and a method on that instance An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references Any object will perfectly do; all that matters is that the method's argument types and return type match the delegate's This makes delegates suited for anonymous invocation
Delegati
In C#, la dichiarazione di un nuovo tipo di delegato definisce automaticamente una nuova classe derivata dalla classe System.MulticastDelegate
Ingegneria del Software T Ingegneria del Software T
16
Pertanto, sulle istanze di Action possibile invocare i metodi definiti a livello di classi di sistema
Delegati
Object ICloneable interface ISerializable
Delegate
+ property Method : System.Reflection.MethodInfo + property Target : System.Object # Delegate ( [in] target : System.Object , [in] method : System.String ) # Delegate ( [in] target : System.Type , [in] method : System.String ) + GetObjectData ( [in] info : System.Runtime.Serialization.SerializationInfo , [in] context : System.... + Clone ( ) : System.Object # RemoveImpl ( [in] d : System.Delegate ) : System.Delegate # CombineImpl ( [in] d : System.Delegate ) : System.Delegate # GetMethodImpl ( ) : System.Reflection.MethodInfo + GetInvocationList ( ) : System.Delegate[] # DynamicInvokeImpl ( [in] args : System.Object[] ) : System.Object + GetHashCode ( ) : System.Int32 + Equals ( [in] obj : System.Object ) : System.Boolean + DynamicInvoke ( [in] args : System.Object[] ) : System.Object + Combine ( [in] a : System.Delegate , [in] b : System.Delegate ) : System.Delegate + Combine ( [in] delegates : System.Delegate[] ) : System.Delegate + Remove ( [in] source : System.Delegate , [in] value : System.Delegate ) : System.Delegate + CreateDelegate ( [in] type : System.Type , [in] target : System.Object , [in] method : System.Str... + CreateDelegate ( [in] type : System.Type , [in] target : System.Object , [in] method : System.Str... + CreateDelegate ( [in] type : System.Type , [in] target : System.Type , [in] method : System.Strin... + CreateDelegate ( [in] type : System.Type , [in] method : System.Reflection.MethodInfo ) : Syste... + get Method ( ) : System.Reflection.MethodInfo + get Target ( ) : System.Object + op_Equality ( [in] d1 : System.Delegate , [in] d2 : System.Delegate ) : System.Boolean + op_Inequality ( [in] d1 : System.Delegate , [in] d2 : System.Delegate ) : System.Boolean + RemoveAll ( [in] source : System.Delegate , [in] value : System.Delegate ) : System.Delegate
+ GetObjectData ( )
delegate MulticastDelegate
Delegati
Esempio
Action action = new Action(ToUpper) + new Action(TrimStart) + new Action(TrimEnd); foreach (Action a in action.GetInvocationList()) Console.WriteLine(a.Method.Name); ToUpper TrimStart TrimEnd foreach (Action a in action.GetInvocationList()) Console.WriteLine(a.Method.ToString()); System.String ToUpper(System.String ByRef) System.String TrimStart(System.String ByRef) System.String TrimEnd(System.String ByRef)
18
Delegati
Esempio Boss-Worker
necessario modellare uninterazione tra due componenti
un Worker che effettua unattivit (o lavoro) un Boss che controlla lattivit dei suoi Worker quando il lavoro inizia quando il lavoro in esecuzione quando il lavoro finisce class-based callback relationship interface-based callback relationship delegate-based callback relationship eventi
Soluzioni possibili:
- _boss
use
More flexible than class-based design Does not constrain implementer's choice of base type As with class-based approach, requires callee to conform to/change type hierarchy
- _target
interface IWorkerEvents + WorkStarted ( [in] worker : Worker ) + WorkProgressing ( [in] worker : Worker ) + WorkCompleted ( [in] worker : Worker ) : int
use
Boss + WorkStarted ( [in] worker : Worker ) + WorkProgressing ( [in] worker : Worker ) + WorkCompleted ( [in] worker : Worker ) : int
Pattern OBSERVER
Context A change in one object (the subject) will sometimes require other objects (observers) to be updated This relationship can be explicitly coded in the subject, but this requires knowledge about, how the observers should be updated The result is that the objects become intertwined (closely coupled) and can't easily be reused Solution Create a loosely-bound one-to-many relationship between an object and others that depend on it A change in the object will result in the others receiving a notification, enabling them to update themselves accordingly
Pattern OBSERVER
There are two mechanisms which can be used to implement a loose coupling between a subject and its observers Dependency allows an observer to register an interest in ALL aspects of another object
the observer then has to sort out what actually changed at runtime so it can do something sensible in response
Events allow an observer to register an interest in a specific aspect of another object (publisher) and even request that a particular message is routed to them
Pattern OBSERVER
29
Do not require type compatibility like classes/interfaces Enforce only a single method signature (not a name) Act like a tiny interface with one method Facilitate component integration without source code access Support multiple call targets Support asynchronous method invocation
delegate void WorkStarted(Worker worker); delegate void WorkProgressing(Worker worker); delegate int WorkCompleted(Worker worker);
delegate WorkStarted
+ Started
+ Started
WorkStarted
+ Completed WorkCompleted
36
A multicast delegate
39
Public registration methods coupled with private delegate field is better, but tedious if done manually event modifier automates support for
delegate WorkStarted
+ Started
event + Progressing delegate WorkProgressing event Worker + DoWork ( ) use Boss + WorkCompleted ( [in] worker : Worker ) : int
delegate WorkCompleted
event + Completed
TECNICHE AVANZATE
TECNICHE AVANZATE
Eventi
Evento: Fatto o avvenimento determinante nei confronti di una situazione oggettiva o soggettiva In programmazione, un evento pu essere scatenato
dallinterazione con lutente (click del mouse, ) dalla logica del programma
Event sender loggetto (o la classe) che scatena (raises o triggers) levento (sorgente dellevento) Event receiver loggetto (o la classe) per il quale levento determinante e che quindi desidera essere notificato quando levento si verifica (cliente) Event handler il metodo (dellevent receiver) che viene eseguito allatto della notifica
Eventi
Quando si verifica levento, il sender invia un messaggio di notifica a tutti i receiver in pratica, invoca gli event handler di tutti i receiver In genere, il sender NON conosce n i receiver, n gli handler Il meccanismo che viene utilizzato per collegare sender e receiver/handler il delegato (che permette invocazioni anonime)
Dichiarazione di un evento
Un evento incapsula un delegato quindi necessario dichiarare un tipo di delegato prima di poter dichiarare un evento By convention, event delegates in the .NET Framework have two parameters
the source that raised the event and the data for the event
Custom event delegates are needed only when an event generates event data Many events, including some user-interface events such as mouse clicks, do not generate event data In such situations, the event delegate provided in the class library for the no-data event, System.EventHandler, is adequate
Dichiarazione di un evento
public delegate void EventHandler( object sender, EventArgs e); System.Object System.Delegate System.MulticastDelegate System.EventHandler La classe System.EventArgs viene utilizzata quando un evento non deve passare informazioni aggiuntive ai propri gestori Se i gestori dellevento hanno bisogno di informazioni aggiuntive, necessario derivare una classe dalla classe EventArgs e aggiungere i dati necessari
50
Dichiarazione di un evento
public event EventHandler Changed; In pratica, Changed un delegato, ma la keyword event ne limita la visibilit e le possibilit di utilizzo Una volta dichiarato, levento pu essere trattato come un delegato di tipo speciale in particolare, pu: essere null se nessun cliente si registrato
Invocazione di un evento
Per scatenare un evento opportuno definire un metodo protetto virtuale OnNomeEvento invocare sempre quello
public event EventHandler Changed; protected virtual void OnChanged() { if(Changed != null) Changed(this, EventArgs.Empty); } OnChanged();
Ingegneria del Software T Ingegneria del Software T
52
Limitazione rispetto ai delegati Linvocazione dellevento pu avvenire solo allinterno della classe nella quale levento stato dichiarato (bench levento sia stato dichiarato public)
Agganciarsi a un evento
(hooking up to an event)
Al di fuori della classe in cui levento stato dichiarato, un evento viene visto come un delegato con accessi molto limitati Le sole operazioni effettuabili sono: Aggiungere un nuovo delegato alla lista dei delegati mediante loperatore +=
Agganciarsi a un evento
(hooking up to an event)
Per iniziare a ricevere le notifiche di un evento, il cliente deve: Definire il metodo (event handler) che verr invocato allatto della notifica dellevento (con la stessa signature dellevento):
Ingegneria del Software T Ingegneria del Software T
54
Aggiungere il delegato alla lista dei delegati associati allevento, utilizzando loperatore +=:
List.Changed += listChangedHandler;
Sganciarsi da un evento
Per smettere di ricevere le notifiche di un evento, il cliente deve: Rimuovere il delegato dalla lista dei delegati associati allevento, utilizzando loperatore -=:
Ingegneria del Software T Ingegneria del Software T
55
List.Changed -= listChangedHandler; Per aggiungere e rimuovere un delegato dalla lista dei delegati associati allevento si pu anche scrivere: List.Changed += new EventHandler(ListChanged); List.Changed -= new EventHandler(ListChanged); List.Changed += ListChanged; List.Changed -= ListChanged; // // C# 2.0 C# 2.0
Eventi
Since += and -= are the only operations that are permitted on an event outside the type that declares the event, external code
can add and remove handlers for an event, but cannot in any other way obtain or modify the underlying list of event handlers
Events provide a generally useful way for objects to signal state changes that may be useful to clients of that object Events are an important building block for creating classes that can be reused in a large number of different programs
Metadati e introspezione
Metadata
Metadata is data that describes other data. For example, the definition of a class is metadata
Rumbaugh, J. et al, Object Oriented Modeling and Design [Prentice Hall, 1991]
C++ Metadata
A C++ header file may be considered metadata Clients can include this file at compile time to use the types it declares Clients then link with the types definition C++ has also added support for RTTI (Run-Time Type Information), a very limited runtime metadata facility
COM IDL
import "oaidl.idl"; import "ocidl.idl"; #include "olectl.h" [ object, uuid(29AABB7F-E702-11D2-89CF-004033412CFC), dual, helpstring("IPolyCtl Interface"), pointer_default(unique) ] interface IPolyCtl : IDispatch { [ propget, id(1), helpstring("property Sides") ] HRESULT Sides([out, retval] short *pVal); [ propput, id(1), helpstring("property Sides") ] HRESULT Sides([in] short newVal); };
IDL
Reflection
IDLs are an additional requirement for developers to understand Interface Repositories and Type Libraries can be housed in separate files to the type they describe Java/.NET use reflection The metadata is generated from the types definition The metadata is stored with the types definition if you have the definition you have the metadata and vice versa
Reflection
Reflection can be used
Ingegneria del Software T Ingegneria del Software T
8
To examine the details of an assembly To instantiate objects and call methods discovered at runtime To create, compile, and execute assemblies on the fly
.NET classes that deal with providing reflection can be found in:
Application Domain
Assembly Assembly
Ingegneria del Software T Ingegneria del Software T
9
Module Type
System.Type
System.Type is the focal point of reflection
Ingegneria del Software T Ingegneria del Software T
10
All objects and values are instances of types Can discover type of object or value Type t0 = obj.GetType(); Type t1 = "Pippo".GetType(); Can reference type by symbolic name Type t2 = typeof(System.String); Type t3 = Type.GetType("System.String"); Types are themselves instances of type System.Type
There is a single Type object for each type defined in the system
System.Type
11
System.Type
Esempio 5.1
Ingegneria del Software T Ingegneria del Software T
12
System.Type
Some methods:
Ingegneria del Software T Ingegneria del Software T
13
Type[] GetInterfaces(); MemberInfo[] GetMembers(); ConstructorInfo[] GetConstructors(); MethodInfo[] GetMethods(); FieldInfo[] GetFields(); PropertyInfo[] GetProperties(); EventInfo[] GetEvents(); object[] GetCustomAttributes();
14
Esempio 5.2
15
Esempio
Enumerating all types in an Assembly Use Assembly.Load to load a .NET assembly returns an Assembly Assembly.GetModules returns an array of Module For each Module, call Module.GetTypes returns an array of Type For each Type,
1.
2.
Ingegneria del Software T Ingegneria del Software T
16
3.
4.
Esempio 5.3
Can instantiate type in memory, choosing constructor to call Activator.CreateInstance(type, ) Can invoke methods methodInfo.Invoke() Can invoke property getters and setters propertyInfo.GetValue() propertyInfo.SetValue()
Public members always accessible Non-public members accessible if callers hold sufficient permissions
Esempio 5.4
System.Activator
Dynamically create instances Activator.CreateInstance is the late-bound equivalent to operator new
Allocates storage for new type instance Calls specified constructor Returns generic object reference
Esempio 5.5
TECNICHE AVANZATE
Meta-Programming
... the fundamental problem is always the same: preserve information available at compile time for inspection at runtime. Making such information about a system available within that system is called reification. Programming a system to not only use reified information but also to manipulate this information is called meta-programming. meta-programming can be used to dynamically create new classes, insert them into an existing inheritance graph and instantiate them
Szyperski, C., Component Software [Addison-Wesley, 1998]
TECNICHE AVANZATE
Meta-Programming in .NET
A number of classes function together to achieve this goal in .NET By using the previous objects, and others, you can build an assembly on the fly
Reflection.Emit allows you to write out the IL necessary to create and compile the assembly You can then call this assembly from with the program that created it The assembly can be stored to disk so that other programs can use it
TECNICHE AVANZATE
Meta-Programming in .NET
System.Reflection
AssemblyName
Fully describes an assembly's unique identity
System.Reflection.Emit
AssemblyBuilder
Defines and represents a dynamic assembly
ModuleBuilder
Defines and represents a module
TypeBuilder
Defines and creates new instances of classes during runtime
MethodBuilder
Defines and represents a method (or constructor) on a dynamic class
ILGenerator
Generates Microsoft intermediate language (MSIL) instructions
TECNICHE AVANZATE
Assembly: MyAssembly Module: MyModule Type: Esempio5.MyType Method: MyMethod WriteLine("Hello World!");
Ingegneria del Software T Ingegneria del Software T
22
Esempio 5.6
Custom Attributes
Are an easy way to add information to the metadata for any application element
Are supported in any .NET language Are really just common classes that derive from System.Attribute
Declare constructors Declare properties Apply the AttributeUsageAttribute (opzionale) Specifies some of the characteristics of the class
The target of the attribute (AttributeTargets) a quali elementi lattributo applicabile Whether or not the attribute can be inherited (Inherited) Whether or not multiple instances of an attribute can exist for an element (AllowMultiple)
by position or by name
Primo argomento del costruttore
[ Author("Bellavia", Contact="giuseppe.bellavia@unibo.it") ]
Nome di una propriet
inherit specifies whether to search this member's inheritance chain to find the attributes X
Esempio 5.7
Garbage Collector
Utilizzo di un oggetto
In un ambiente object-oriented, ogni oggetto che deve essere utilizzato dal programma
descritto da un tipo Ha bisogno di unarea di memoria dove memorizzare il suo stato Allocare memoria per loggetto in seguito a una new (istruzione newobj di IL) Inizializzare la memoria per rendere utilizzabile loggetto valori di default + costruttore Usare loggetto Eseguire un clean up dello stato delloggetto, se necessario Finalize (distruttore in C# e C++), Dispose, Close Liberare la memoria responsabilit del Garbage Collector (GC)
Riserva una regione contigua di spazio di indirizzamento managed heap Memorizza in un puntatore (NextObjPtr) lindirizzo di partenza della regione
NextObjPtr
Calcola la dimensione in byte delloggetto e aggiunge alloggetto due campi di 32 (o 64) bit
Un puntatore alla tabella dei metodi Un campo SyncBlockIndex
Controlla che ci sia spazio sufficiente a partire da NextObjPtr in caso di spazio insufficiente:
garbage collection OutOfMemoryException
thisObjPtr = NextObjPtr; NextObjPtr += sizeof(oggetto); Invoca il costruttore delloggetto (this thisObjPtr) Restituisce il riferimento alloggetto
NextObjPtr
Tecnica di allocazione completamente diversa da quella del C/C++ Oggetti vivi Oggetti non raggiungibili Spazio libero
Garbage Collector
Verifica se nellheap esistono oggetti non pi utilizzati dallapplicazione
Ingegneria del Software T Ingegneria del Software T
7
Ogni applicazione ha un insieme di radici (root) Ogni radice un puntatore che contiene lindirizzo di un oggetto di tipo riferimento oppure vale null Le radici sono:
Variabili globali e field statici di tipo riferimento Variabili locali o argomenti attuali di tipo riferimento sugli stack dei vari thread Registri della CPU che contengono lindirizzo di un oggetto di tipo riferimento
Gli oggetti vivi sono quelli raggiungibili direttamente o indirettamente dalle radici Gli oggetti garbage sono quelli NON raggiungibili direttamente o indirettamente dalle radici
Garbage Collector
Quando parte, il GC ipotizza che tutti gli oggetti siano garbage Quindi, scandisce le radici e per ogni radice marca
Ingegneria del Software T Ingegneria del Software T
8
Leventuale oggetto referenziato e Tutti gli oggetti a loro volta raggiungibili a partire da tale oggetto
Sia per motivi di prestazioni Sia per gestire correttamente riferimenti ciclici
Una volta terminata la scansione delle radici, tutti gli oggetti NON marcati sono non raggiungibili e quindi garbage
NextObjPtr
Root set
Garbage Collector
Rilascia la memoria usata dagli oggetti non raggiungibili Compatta la memoria ancora in uso, modificando nello stesso tempo tutti i riferimenti agli oggetti spostati! Unifica la memoria disponibile, aggiornando il valore di NextObjPtr Tutte le operazioni che il GC effettua sono possibili in quanto
10
Il tipo di un oggetto sempre noto possibile utilizzare i metadati per determinare quali field delloggetto fanno riferimento ad altri oggetti
Root set
Finalization
Non responsabilit del GC, ma del programmatore Se un oggetto contiene esclusivamente
(maggior parte dei casi), non necessario eseguire alcun codice particolare Se un oggetto contiene almeno un riferimento a un oggetto unmanaged (in genere, una risorsa del S.O.)
necessario eseguire del codice per rilasciare la risorsa, prima della deallocazione delloggetto
Finalization
Ad esempio, un oggetto di tipo System.IO.FileStream
Prima deve aprire un file e memorizzare in un suo field lhandle del file (una risorsa di S.O. unmanaged) Quindi usa tale handle nei metodi Read e Write Infine, deve rilasciare lhandle nel metodo Finalize
In C#
NON possibile definire il metodo Finalize necessario definire un distruttore (sintassi C++)
Finalization
public class OSHandle { // Field contenente lhandle della risorsa unmanaged private readonly IntPtr _handle; // Propriet che restituisce il valore dellhandle public IntPtr Handle { get { return _handle; } } public OSHandle(IntPtr handle) { _handle = handle; } OSHandle() { CloseHandle(_handle); } [System.Runtime.InteropServices.DllImport(Kernel32)] private extern static bool CloseHandle(IntPtr handle); }
14
Finalization
Il compilatore C# trasforma il codice del distruttore
OSHandle() { CloseHandle(_handle); }
Finalization
Il metodo Finalize dovrebbe essere utilizzato solo per rilasciare risorse unmanaged che appartengono alloggetto su cui eseguire il metodo Nel metodo Finalize si dovrebbe evitare di accedere ad altri oggetti managed
Potrei cercare di accedere a un oggetto sul quale il GC ha gi invocato il corrispondente metodo Finalize e che quindi potrebbe essere in uno stato non ben definito
Tutti i metodi Finalize vengono eseguiti in un thread dedicato (diverso da quello del GC) pertanto, nel codice non si devono fare ipotesi sul thread in esecuzione
Il pattern Dispose
Linvocazione del metodo Finalize non avviene in modo deterministico Inoltre, non essendo un metodo pubblico, il metodo Finalize non pu essere invocato direttamente Nel caso di utilizzo di risorse che devono essere rilasciate appena termina il loro uso, questa situazione problematica Si pensi a file aperti o a connessioni a database che vengono chiusi solo quando il GC invoca il corrispondente metodo Finalize In questi casi, di fondamentale importanza rilasciare (Dispose) o chiudere (Close) la risorsa in modo deterministico
Il pattern Dispose
I tipi che vogliono offrire questa funzionalit devono implementare il pattern Dispose Il pattern Dispose fissa le convenzioni da seguire quando si vuole definire un tipo in grado di offrire un servizio di clean up esplicito ai suoi utilizzatori Innanzi tutto, il tipo deve implementare linterfaccia IDisposable
public interface IDisposable { void Dispose(); }
18
Il pattern Dispose
public class MyClass : IDisposable { // Riferimenti a risorse unmanaged // Riferimenti a risorse managed // che contengono riferimenti a risorse unmanaged // e che quindi implementano IDisposable Invocazione NON // Costruttore/i deterministica ~MyClass() { Dispose(false); }
Il pattern Dispose
// Metodo da invocare per un rilascio deterministico public void Dispose() Invocazione { deterministica Dispose(true); // Take yourself off of the Finalization queue to prevent // finalization code for this object from executing a second time GC.SuppressFinalize(this); } // Metodo alternativo (opzionale) per una chiusura deterministica public void Close() { Dispose(); }
Il pattern Dispose
// Track whether Dispose has been called private bool _disposed = false; protected virtual void Dispose(bool disposing) { // Syncronize threads calling Dispose/Close simultaneously lock (this) { if(!_disposed) // Check to see if Dispose has already been called { if(disposing) { // Dispose managed resources } // Dispose unmanaged resources _disposed = true; } } }
Il pattern Dispose
Dispose(bool disposing) executes in two distinct scenarios:
if disposing == true, the method has been called directly or indirectly by a user's code Managed and unmanaged resources can be disposed if disposing == false, the method has been called by the runtime from inside the finalizer and you should not reference other objects Only unmanaged resources can be disposed
Il pattern Dispose
// Allow your Dispose method to be called multiple times, // but throw an exception if the object has been disposed // Whenever you do something with this class, // check to see if it has been disposed public void DoSomething() { if(_disposed) throw new ObjectDisposedException(); }
Il pattern Dispose
in una classe derivata
private bool _disposed = false; protected override void Dispose(bool disposing) { lock (this) { if(!_disposed) { try { if(disposing) { // Dispose managed resources } // Dispose unmanaged resources _disposed = true; } finally { base.Dispose(disposing); } } } }
Il pattern Dispose
dal lato del cliente senza using
Byte[] bytesToWrite = new Byte[] {1,2,3,4,5}; FileStream fs = null; try { fs = new FileStream(Temp.dat, FileMode.Create); fs.Write(bytesToWrite, 0, bytesToWrite.Length); } finally { if(fs != null) fs.Close(); }
Il pattern Dispose
dal lato del cliente con using
Byte[] bytesToWrite = new Byte[] {1,2,3,4,5}; using (FileStream fs = new FileStream(Temp.dat, FileMode.Create)) { fs.Write(bytesToWrite, 0, bytesToWrite.Length); }
Alluscita del blocco using, viene sempre invocato automaticamente il metodo Dispose Il tipo della variabile definita nella parte iniziale di using deve implementare linterfaccia IDisposable
Interfaccia utente
System.Windows.Forms
The System.Windows.Forms namespace contains classes for creating Windows-based applications The classes can be grouped into the following categories:
Ingegneria del Software T Ingegneria del Software T
2
System.Windows.Forms
Idle Processing
Windows/Dialog Boxes
Form
ZZZ
Message Handling / Application Lifetime
System.Windows.Forms. Application
Menus
MenuItem MainMenu ContextMenu
Controls
Button ComboBox ListBox TextBox DataGrid Etc
Spy++
Derived classes
Ingegneria del Software T Ingegneria del Software T
7
Affect instance appearance and behavior by setting properties Create objects to implement GUI controls
Buttons, text boxes, menus, timers, custom controls, etc.
System.Drawing namespace
Full of types used heavily in windows applications Implements basic graphic objects
Classes: Graphics, Font, Brush, Pen, Icon, Bitmap, ... Instance Creators: Brushes, Pens, SystemBrushes, SystemColors, SystemIcons, Cursors Structures: Point, Size, Rectangle, Color, ... Important class that represents a drawing surface Can be in-memory, form-based, or HDC-based Used by forms applications to draw and paint on controls
DrawString(), DrawImage(), FillEllipse(), FillRectangle(), ...
System.Drawing.Graphics
System.Windows.Forms.Application
Non-instantiable class with public static methods and properties Used to handle windows-application infrastructure
Ingegneria del Software T Ingegneria del Software T
10
Controls
A control is a component that provides (or enables) user-interface (UI) capabilities The .NET Framework provides two base classes for controls:
System.Windows.Forms.Control
for client-side Windows Forms controls
System.Web.UI.Control
for ASP.NET server controls
All controls in the .NET Framework class library derive directly or indirectly from these two classes
Controls
The System.Windows.Forms namespace provides a variety of control classes that allow you to create rich user interfaces Some controls are designed for data entry
The namespace also provides controls for invoking commands within the application
Button, ToolBar,
Provides the base functionality for all controls that are displayed on a Form Derives from Component Wraps an underlying OS window handle Properties for modifying settings of an instance
Size, BackColor, ContextMenu, ...
Implements many
To create a custom control that is a composite of other controls, use the UserControl class
System.Windows.Forms.Form
A specialized derivation of Control used to implement a top-level window or dialog Gains much of its functionality from base classes Specialized to
Contain a main menu Contain a title-bar, system menu, minimize/maximize Implement MDI - Multiple Document Interface Manage dialog buttons ... Windows Dialog boxes
Using Forms
Create a Form-derived class
class BlueForm : Form { public BlueForm() { BackColor = Color.Blue; } }
Using Forms
In the types constructor
Ingegneria del Software T Ingegneria del Software T
17
Set properties Create child controls Use the Controls property to add controls to the form Setup the forms menu OnFormClosing(), OnPaint(), OnMouseMove(), ... Do not override when default functionality is ok (usually the case) When overriding a virtual method, usually call the baseimplementation of the method
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // Do some work }
Using Controls
Create the control
Button ctrl = new Button(); // Create a button
Set properties
Ingegneria del Software T Ingegneria del Software T
19
ctrl.Text = "A Button"; // set its text ctrl.Location = new Point(10, 10); // and location
The OpenFileDialog and SaveFileDialog classes provide the functionality to display a dialog box that allows the user to browse to and enter the name of a file to open or save The FontDialog class displays a dialog box to change elements of the Font object used by your application The PageSetupDialog, PrintPreviewDialog, and PrintDialog classes display dialog boxes that allow the user to control aspects of printing documents
In addition, the System.Windows.Forms namespace provides the MessageBox class for displaying a message box that can display and retrieve data from the user
Components
In programming, the term component is generally used for an object that is reusable and can interact with other objects A .NET Framework Component satisfies those general requirements and additionally provides features such as
Control over unmanaged resources Design-time support A component can be used in a rapid application development (RAD) environment A component can be added to the toolbox of Visual Studio .NET, can be dragged and dropped onto a form, and can be manipulated on a design surface Note that base design-time support is built into the .NET Framework; a component developer does not have to do any additional work to take advantage of the base design-time functionality
Components
The System.Windows.Forms namespace provides classes that do not derive from the Control class but still provide visual features to a Windows-based application The ToolTip and ErrorProvider classes provide information to the user The Menu, MenuItem, and ContextMenu classes provide the ability display menus to the user to invoke commands within an application The Help and HelpProvider classes enable you to display help information to the user of your applications
Menu.MenuItemCollection
Add sub-MenuItems
MenuItem menuItem2 = new MenuItem("E&xit"); menuItem1.MenuItems.Add(menuItem2);
Code Code
Data
Programmazione strutturata
Goto
Code
Data
Code
Data Code
Obiettivo
Nascondendo le scelte progettuali (spesso soggette a cambiamenti), si proteggono le altre parti del programma (i clienti dellADT) da eventuali cambiamenti di tali scelte
Vantaggi
Minimizzazione delle modifiche da fare durante le fasi di sviluppo e di manutenzione Aumento della possibilit di riutilizzo
Implementazione:
Array Linked list
1 2 2 3
Data
ArrayList
lista
Data
lista
Data
1
lista
lista
Abstract Code
Static Data
Code
Abstract Code
ArrayList LinkedList
Data
Static Data
Static Data
Data
Data
Data
10
4 at sil
Code
Code
3 at sil
1 at sil 2 at sil
11
Compile time, ogni classe definisce limplementazione di un tipo di dato astratto Run time, ogni oggetto unistanza di una classe (traduzione comune anche se impropria del termine instance) Un'istanza un particolare oggetto di una determinata classe e quindi di un particolare tipo Ogni istanza separata dalle altre, ma condivide le sue caratteristiche generali con gli altri oggetti della stessa classe
12
Notazione UML
Una classe si rappresenta come un rettangolo diviso in 1 o 3 sezioni
attore Esaminando matricola cognome nome GetMatricola() GetCognomeNome() EffettuaEsame() Stereotipo
Attributi
Operazioni
13
Notazione UML
La prima sezione contiene
il nome della classe (in grassetto + in corsivo se astratta)
attore Esaminando matricola cognome nome GetMatricola() GetCognomeNome() EffettuaEsame()
pu contenere
lo stereotipo della classe (ad esempio, controllore, attore, evento, tabella, ecc.) il nome del pacchetto (package, namespace ad esempio, Quizzer::Esaminando)
Notazione UML
interface interface
IEsaminando EffettuaEsame()
attore Esaminando matricola cognome nome GetMatricola() GetCognomeNome() EffettuaEsame() 15 Ingegneria del Software T
Notazione UML
attore Esaminando IStudente matricola cognome nome GetMatricola() GetCognomeNome() EffettuaEsame()
IEsaminando
16
Notazione UML
ArrayList
lista1:ArrayList
instanceOf
:Arra yList
lis ta1
17
19
Ereditariet (inheritance)
Model inheritance
Subtype inheritance Extension inheritance Restriction inheritance View inheritance
reflecting "is-a" relations between abstractions in the model
Software inheritance
Reification inheritance Structure inheritance Implementation inheritance Facility inheritance
Constant inheritance Machine inheritance expressing relations within the software itself rather than in the model
Variation inheritance
Functional variation inheritance Type variation inheritance Uneffecting inheritance
20 Ingegneria del Software T
a special case that may pertain either to the software or to the model
Ereditariet
Ereditariet di interfaccia o subtyping (ed ereditariet di estensione)
meccanismo di compatibilit fra tipi: una sottoclasse un sottotipo compatibile con tutti i tipi definiti lungo la sua catena ereditaria (relazione IsA) consente il polimorfismo per inclusione
21
Docente
Studente
Non detto che una Persona sia un Docente o uno Studente E se una Persona sia un Docente, sia uno Studente?
22 Ingegneria del Software T
Ereditariet di realizzazione
Spesso una classe ha bisogno di utilizzare i servizi di unaltra classe Ad esempio, la classe Finestra ha bisogno di utilizzare la classe Rettangolo per
memorizzare posizione e dimensione fare calcoli di sovrapposizione con altre finestre ...
Potrei definire Finestra come sottoclasse di Rettangolo (ma una Finestra NON un Rettangolo)
Finestra eredita e quindi ha accesso diretto a dati e operazioni (public e protected) di Rettangolo i clienti della classe Finestra NON hanno accesso a dati e operazioni (anche se public) della classe Rettangolo
23 Ingegneria del Software T
Ereditariet di realizzazione
In C++:
public class Finestra : private Rettangolo
Retta ngolo
La definizione statica (compile-time) Limplementazione della sottoclasse facile da modificare, pu definire i propri metodi e continuare a usare quelli della superclasse La superclasse definisce parte della rappresentazione fisica della sottoclasse, legando a s la sottoclasse, rompendo lincapsulamento (Finestra vede i membri protected di Rettangolo) e rendendo pi difficile il riuso della sottoclasse
24 Ingegneria del Software T
Fine stra
Composizione e delega
Esiste unalternativa pi interessante: inserire un Rettangolo nella struttura dati di una Finestra: una Finestra contiene un Rettangolo (una Finestra composta, tra le altre cose, da un Rettangolo) Una Finestra ha accesso indiretto alle operazioni pubbliche di un Rettangolo (una Finestra delega al Rettangolo lesecuzione di alcuni compiti) Le interfacce delle classi restano indipendenti
Ingegneria del Software T
Retta ngolo
Fine stra
25
Composizione e delega
Lassociazione tra Finestra e Rettangolo pu avvenire dinamicamente (run-time) Maggiore flessibilit ed estendibilit!
Retta ngolo Fine stra
Figura
Cerc hio
Quindi
se e solo se vale la relazione IsA, usare lereditariet altrimenti, usare la composizione
26 Ingegneria del Software T
Polimorfismo
Capacit
della stessa cosa di apparire in forme diverse in contesti diversi di cose diverse di apparire sotto la stessa forma in un determinato contesto
27
Polimorfismo
Classificazione Cardelli-Wegner
Programmazione object-oriented
Programmazione generica
5 + 10 5.2 + 11.7
5 + 11.7
28
29
Ereditariet
Ereditariet semplice ogni classe della gerarchia deriva
da una e una sola superclasse (Java, .NET) al pi da una superclasse (C++) la struttura che si ottiene sempre un albero
Ereditariet multipla almeno una classe della gerarchia deriva da 2+ superclassi (possibile in C++) Se esistono antenati comuni
la struttura che si ottiene un reticolo si hanno conflitti di nome la gestione pu diventare molto complessa
30
Ereditariet multipla
Tra due o pi classi di una gerarchia possono esistere dei vincoli {overlapping} o {disjoin}
Veicolo {overlapping} {disjoint}
VeicoloTerrestre
VeicoloAcquatico
VeicoloMilitare
VeicoloCivile
CarroArmato
Taxi
Corazzata
BarcaAVela
Un reticolo di veicoli
31
Ereditariet multipla
Veicolo OggettoMilitare
CarroArmato
Taxi
Corazzata
BarcaAVela
32
Esempi
Docente Docenti (contiene una collezione di docenti) CorsoDiStudio CorsiDiStudio AttivitaFormativa AttivitFormativa accettato in C#
33 Ingegneria del Software T