UML e gli Oggetti, Introduzione ad UML

« Older   Newer »
  Share  
Hellblow
view post Posted on 17/12/2007, 22:39




UML (Unified Modelling Language) è uno strumento estremamente potente e facile da usare che nelle mani di un progettista capace è in grado di rappresentare qualsiasi sistema.
Possiamo rappresentare in UML il funzionamento di un computer, di un impianto di riscaldamento, di un sistema informativo o di un robot.
L'importanza di UML risiede nel fatto che fornisce delle regole generali per la rappresentazione dei sistemi, regole che definiscono una linea guida in grado di rendere comprensibilissimo un progetto.
UML non si limita solo a quanto sopra scritto. Infatti partire direttamente con l'implementazione di un sistema senza averne fatto prima un'analisi porta molto spesso a punti morti che rendono difficile proseguire. Lo studio tramite UML mette in risalto tutte le problematiche legate al progetto e dunque consentono di approfondire le soluzioni a questi problemi. UML si basa su tre elementi fondamentali:

1) Viste: che sono interpretabili come diversi modi di vedere un sistema
2) Diagrammi: che sono la maniera con cui graficamente si rappresentano gli aspetti del progetto
3) Componenti: che costituiscono i diagrammi

Infatti UML permette una rappresentazione grafica del progetto rendendolo estremamente conprensibile.
Prima di cominciare a parlare in maniera piu' approfondita di UML è indispensabile spiegare cosa è un Oggetto.

Prendiamo un libro fra le mani ed osserviamolo. Un libro possiede ad esempio una copertina che ha un certo colore, un certo numero di pagine, un formato, un peso. Tutti questi elementi sono delle CARATTERISTICHE del nostro libro, che possiamo considerare un oggetto. Quini un oggetto possiede delle caratteristiche che prendono il generico nome di ATTRIBUTI. Alcuni attributi puo' essere solo letti, altri consentono la modifica. Ad esempio se pensiamo ad un ascensore fermo ad un certo piano, il numero del piano puo' essere considerato un attributo che però puo' essere modificato. Invece il numero di pagine di un libro è un attributo che puo' essere solo letto. Non possiamo modificare il numero di pagine (a meno di strapparle ;) ).
Adesso lasciamo cadere il nostro libro. Possiamo notare come un'azione esterna come quella delle nostre mani possa influenzare un oggetto. Tale azione esterna si chiama EVENTO.
Posiamo il nostro libro ed osserviamo il lettore di CD del nostro PC. Il lettore puo' svolgere alcune azioni come leggere un cd, scriverci (se è un masterizzatore), espellerlo ecc... Tutte queste azioni si chiamano METODI e sono operazioni che il nostro oggetto puo' svolgere.

Concentriamoci di nuovo sugli ATTRIBUTI. Alcuni attributi sono numerici, altri sono caratteri, altri ancora parole. Come fare ad identificarli? Per far questo si ricorre al concetto di TIPO che identifica la natura di un certo oggetto. Abbiamo i seguenti TIPI (standard):

INTEGER: un numero intero
FLOAT: un numero decimale (non ci soffermiamo per ora sui vari tipi di decimali, ci basta per adesso FLOAT)
CHAR: un carattere
STRING: una sequenza di caratteri
BOOLEAN: un valore che puo' essere o vero o falso


Ad esempio, il numero di pagine di un libro è un INTEGER, il peso di una mela misurato in Kg è un FLOAT, il nostro nome è uno STRING, la prima lettera dell'alfabeto è un CHAR. Ed i BOOLEAN? Supponiamo di chiederci se pesiamo piu' di 60 Kg o meno, la risposta è SI o NO, cioè VERO o FALSO. Ecco che la risposta a quella domanda è un BOOLEAN.
Allora possiamo provare a definire un attributo usando i tipi. Esempi sono:

PagineLibro:Integer
PesoMela:Float
Nome:String

ecc...

Passiamo ai metodi. Un metodo è quasi inutile se non possiamo specificare dei parametri su cui il metodo agisce. Ad esempio supponiamo che un metodo faccia la somma di due numeri. Per far ciò serve dar al metodo i due numeri. Possiamo specificare il metodo in questo modo:

SOMMA(numero1,numero2)

Però facendo cosi' non abbiamo specificato cosa sono numero1 e numero2. Inoltre il nostro metodo deve ritornarci la somma dei due numeri altrimenti non potremo mai conoscere il risultato di quella somma. Per far ciò useremo la:

SOMMA(numero1:Integer , numero2:Integer):Integer

In pratica abbiamo scritto che SOMMA accetta due interi in ingresso e ritorna un intero in uscita. Tralasciando ora le istruzioni necessarie a svolgere il compito, supponiamo di voler utilizzare il metodo. Per esempio sommiamo 4 e 5:

SOMMA(4,5)

SOMMA ritornerà come valore 9. Però serve che questo valore venga messo dentro qualche cosa che funga da contenitore per non perdere l'informazione. Chiamiamo Temp questo contenitore che deve essere un intero. Ad esempio:

Temp:Integer
Temp=SOMMA(4,5)

bene adesso Temp dovrebbe contenere il valore ritornato da SOMMA. Immaginiamo di disporre di un altro metodo che stampa su schermo il valore di una certa variabile (il 'contenitore' che abbiamo usato prima, ovvero Temp) definito come:

STAMPA(NumeroDaStampare:Integer)

Si noti che STAMPA non ci ritorna nulla ma esegue un'operazione proiettando il risultato su schermo. Non tutti i metodi infatti ritornano un risultato.
Proviamo ad usarlo:

Temp:Integer
Temp=SOMMA(4,5)
STAMPA(Temp)

Il risultato sarà 9 e verrà stampato su schermo.
Quanto abbiamo scritto fino ad ora è una specie di pseudocodice (ovvero non è un linguaggio di programmazione ben definito, ma creato ad Hoc da noi) che però rispecchia molto delle regole usate da UML.

Facciamo un passo in avanti. Prendiamo tutti i libri che abbiamo nella libreria ed osserviamoli. Possiamo notare come la struttura dei libri sia a comune, tutti hanno delle pagine, tutti hanno una copertina, tutti hanno stessi metodi ed eventi, ciò che cambia sono gli attributi. Allora un Libro appartiene ad un insieme che è quello dei Libri. Tale insieme si chiama CLASSE. Quindi la classe mette insieme un insieme di oggetti simili che si differenziano solo per gli attributi. Ad esempio tutte le persone appartengono alla classe PERSONA ma ciascuna ha caratteristiche proprie, sebbene tutte abbiano stessa capacità di azione (metodi).

Prima di concludere questo primo post proviamo a creare una classe usando sempre una sintassi di comodo:

CLASSE orologio

ATTRIBUTI
ore:Integer
minuti:Integer
secondi:Integer

METODI

settaOra(nuovaora:integer)
settaMinuti(nuoviminuti:integer)
settaSecondi(nuovisecondi:integer)
stampaOrario()


La nostra classe di esempio possiede come attributi ora-minuti-secondi che rappresenta l'orario. Inoltre dispone di alcuni metodi che servono a modificare gli attributi e di un metodo (stampaOrario() ) che non necessita di parametri di input o di output e manda allo schermo direttamente l'orario. Questo è un esempio molto semplificato di come costruire una classe, ma rende bene, spero, l'idea di cosa ci appresteremo a fare piu' avanti.

Un saluto...
 
Top
Hellblow
view post Posted on 22/12/2007, 14:49




Seconda parte della nostra breve carrellata su UML.
Quando si realizza un sistema capita spesso che sia necessario interfacciare tale sistema in maniera tale da consentire ad un operatore certe operazioni. L'operatore (che puo' essere un uomo o un altro sistema) prende il nome di attore e rappresenta colui che esegue un'operazione che il sistema che stiamo sviluppando fornisce. Ad esempio volendo trattare il progetto di un ascensore è logico che l'operatore dovrà poter:

1) Chiamare l'ascensore
2) Selezionare il piano di destinazione
3) Suonare un allarme
4) Bloccare la corsa dell'ascensore

Per rappresentare questo punto di VISTA, che prende il nome appunto di USE CASE VIEW, si usa un tipo di diagramma detto Use Case Diagram.
Use Case Diagram ha una serie di caratteristiche che lo rendo ideale per astrarsi dalla vera e propria realizzazione del sistema e dai dettagli tecnici pur consentendo di sottolineare le funzionalità che il sistema deve possedere.
Supponiamo di voler realizzare un robot dotato di cingoli e di un braccio meccanico e di volerlo controllare tramite un operatore (ad esempio i robot che vengono usati per disinnescare e rimuovere esplosivi).
L'attore principale sarà sicuramente l'operatore, che indicheremo con un ominino stilizzato, per convenzione. E' importante indicare sempre il nome dell'attore. Gli Use Case (casi d'uso) invece vengono rappresentati dentro delle ellissi, ed infine la relazione fra l'attore e lo use case è indicata con una linea. Gli use case che sicuramente serviranno sono:

1) Controlla Cingoli
2) Controlla Braccio

Ecco un esempio di come potrebbe essere il nostro diagramma:

image

Il diagramma è molto semplice e si spiega da solo. Osservandolo attentamente possiamo notare come ad esempio Controlla Cingoli in realtà consti di due diversi elementi, ovvero controlla cingolo destro e controlla cingolo sinistro. Sebbene si possa indicare al posto di Controlla Cingoli i due Use Case Controlla Cingolo Destro e Controlla Cingolo Sinistro è ovvio il nesso che lega entrambi ed è probabile che si voglia tenerli insieme.
Gli Use Case Diagram consentono di sfruttare alcune relazioni particolari. Fra queste è molto utile l'inclusione, che consente ad uno Use Case di includere altri Use Case che quindi forniscono al primo diverse operazioni. Il nostro diagramma diventa, considerando anche il braccio (supponiamo sia un braccio dotato di 3 gradi di movimento piu' pinza):

image

Come possiamo notare la relazione di inclusione è specificata dalla <<include>> e dalla presenza della freccia che punta allo Use Case oggetto dell'inclusione.
Probabilmente il nostro Operatore vedendo questo schema comprenderà molto facilmente cosa stiamo mettendo su per lui, ma ci farà notare che pilotare un robot senza una videocamera e qualche sensore è praticamente impossibile. Già qui capiamo che fattori che magari in prima battuta erano stati trascurati saltano fuori realizzando i diagrammi UML. QUindi l'operatore deve essere in grado di:

1) Visualizzare i dati di una telecamera sulla pinza
2) Visualizzare i dati di una telecamera mobile controllata in remoto.
3) Visualizzare messaggi provenienti dal robot (a esempio un avviso che indichi che la pendenza del terreno rischia di far ribaltare il robot)

Procediamo all'angiunta di queste funzionalità.

image

Ecco pronto il nostro primo use case realizzato interamente in paint. Infatti altra caratteristica di UML è la semplicità con cui si rappresentena i diagrammi, cosa che consente di utilizzare carta e penna, Paint o software complessi come Poseidon e Visual Paradigm.
Ad esempio lo stesso diagramma con qualche piccola modifica e realizzato in Poseidon è il seguente:

image

Possiamo associare a questo diagramma una piccola immagine che spieghi in maniera molto semplice alcuni Use Case relazionati al robot. Ad esempio una cosa del genere potrebbe essere molto esplicita se affiancata dallo Use Case:

image

Infatti questo 'scarabocchio in paint' ci spiega a cosa sono associate le funzioni descritte nello Use Case rispetto al nostro robot.

Vediamo un altro Use Case proveniente stavolta dalla rete:

image

Si nota come sia presente una seconda relazione che è Extend. Extend (Estensione) indica che una Use Case viene estesa da un'altra Use Case che presenta le funzioni della prima ma anche funzioni aggiuntive.
L'uso di Extend e Include sarà piu' chiaro quando parleremo degli altri diagrammi. Ci basti sapere per ora che queste relazioni sono utili per specificare delle funzionalità altrimenti nascoste.

Si ricordi inoltre che gli Use Case sono dei diagrammi che vedono il sistema dal punto di vista dell'utente e che quindi non possono certamente essere troppo specifici, ma devono mantenere un certo livello di astrazione da come poi il sistema verrà implementato.

Edited by Hellblow - 22/12/2007, 15:28
 
Top
Hellblow
view post Posted on 10/1/2008, 13:55




Terza parte riguardante UML. Vediamo di introdurre i diagrammi di classe. Abbiamo detto che un oggetto è in grado di rappresentare all'interno del nostro programma un oggetto fisico o non. Una classe puo' fungere da stampo per gli oggetti accomunandoli in base a caratteristiche e funzioni comuni (si parla di Abstract Data Type) e quindi è perfetta per individuare le varie parti che compongono un qualsiasi sistema rappresentando in maniera molto efficace le relazioni che esistono fra le componenti del sistema stesso.
Ad esempio vogliamo modellizzare la telecamera del nostro robot in modo da prelevare delle istantanee scattate dalla stessa.
Sicuramente le funzioni che ci interessano sono quelle legate al movimento ed alla messa a fuoco della stessa, quindi:

SpostaDestra(float gradi)
SpostaSinistra(float gradi)
SpostaAlto(float gradi)
SpostaBasso(float gradi)
Zoom(int valore)

in questo modo noi possiamo interagire con la videocamera decidendo come muoverla e se fare uno zoom. La nostra videocamera dispone internamente di una circuiteria che consente di prelevare le immagini. Possiamo rappresentare questo fatto come un attributo di tipo Immagine (che creeremo ad hoc) che contiene una singola immagine della videocamera. Ovviamente ci servirà anche la funzione che ci consente di poter prelevare questa immagine. Quindi:

Immagine foto
GetFoto()

GetFoto() ritorna un oggetto di tipo Immagine, ovvero ci ritorna la foto. La definizione corretta è quindi:

Immagine GetFoto()

inoltre GetFoto deve poter essere usato anche da classi diverse da se stessa, lo possiamo quindi definire come Publico, ad esempio:

Public Immagine GetImmagine()

Ora, in UML le classi si rappresentano dentro rettangoli divisi in tre aree, dove la prima rappresenta il nome della classe, la seconda gli attributi e la terza i metodi. Quindi abbiamo in pratica (usando sempre Poseidon):

image

Osserviamo attentamente la forma con cui Poseidon realizza la modellazione della classe cosi' da accennare alla sintassi usata da UML per questo tipo di rappresentazioni.

Brevemente, ogni metodo o attributo presenta a sinistra un segno che puo' essere + (Publico) - (Privato) ecc... che ne definisce il modificatore di accesso. Ad esempio Publico vuol dire che tutti gli altri oggetti possono accedere comodamente ai metodi contenuti nella classe.
I tipi sono indicati facendoli seguire a : e piu' a destra, nei metodi, appare il tipo ritornato.
Ad esempio, se chiamiamo il metodo GetImmagine possiamo fare cosi';

MiaImmagine=GetImmagine()

GetImmagine ritorna come risultato un oggetto di tipo immagine che finirà per essere messo dentro MiaImmagine mettendoci a disposizione l'istantanea fatta.
Però se il metodo non fosse +GetImmagine.... ma -GetImmagine allora non potremmo accedere cosi' direttamente al metodo essendo questo privato appunto.
Prossimo post vedremo come collegare fra loro piu' classi.

 
Top
ciavs
view post Posted on 26/7/2009, 22:38




ottima la guida .

ma il prossimo post ?

ciao
 
Top
3 replies since 17/12/2007, 22:39   2367 views
  Share