Object Constraint Language: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Wisbot (discussione | contributi)
m Robot: converting/fixing HTML
Riga 1:
L'<b>'''Object Constraint Language</b>''' o '''OCL''' è un [[Linguaggio formale (matematica)|linguaggio di specifica formale]] inizialmente proposto come estensione per il linguaggio di modellazione [[Paradigma object-oriented|object-oriented]] [[Unified Modeling Language|UML]] e successivamente ([[2003]]) entrato a far parte del nuovo standard del linguaggio (UML 2.0). OCL può essere impiegato insieme a qualunque metamodello basato su [[Meta-Object Facility|MOF]]. Inoltre, OCL è un elemento chiave del nuovo standard per la trasformazione di modelli di OMG, [[QVT]], e fa parte della famiglia di standard che compongono la [[Model Driven Architecture]]. I principali ideatori di OCL sono [[Jos Warmer]] e [[Anneke Kleppe]].
 
OCL deriva da un linguaggio precedente noto come [[Syntropy]]. Il nucleo di OCL può essere descritto come un linguaggio mutuato dal [[calcolo dei predicati del primo ordine]] per l'espressione di condizioni logiche inerenti lo stato e le operazioni di oggetti in un contesto object-oriented. Con la potenza del calcolo dei predicati, OCL consente di descrivere [[invariante|invarianti]] che legano il valore degli attributi di una classe, [[asserzione|precondizioni e postcondizioni]] delle operazioni, e via dicendo. A partire dalla versione 2.0 (che è quella inclusa nello standard UML), il linguaggio è stato arricchito di elementi che consentono di descrivere la semantica di operazioni di tipo ''interrogazione'' (''query''), ovvero prive di [[effetto collaterale|effetti collaterali]].
Riga 9:
In genere, in UML, un'espressione OCL è associata a una ''classe'', e descrive proprietà degli ''oggetti'' istanze di quella classe. Queste proprietà sono espresse in forma di condizioni che legano i valori degli attributi, dei parametri, dei valori tornati delle operazioni, e così via. Nel seguente esempio compare un'espressione che fa riferimento a un attributo:
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>età>=0</code>
 
Riga 16:
Nel caso in cui un attributo di una classe sia a sua volta un oggetto, è possibile riferirsi ai suoi attributi o metodi utilizzando la ''[[dot notation]]'':
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>età>=0 and età<padre.età</code>
 
Riga 26:
L'operatore <code>->size()</code> fornisce la numerosità di una collezione. La seguente regola indica che ogni persona ha due genitori:
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>genitori->size()=2</code>
 
L'operatore <code>->forAll</code> corrisponde al [[quantificatore universale]] del calcolo dei predicati del primo ordine. La seguente regola rappresenta una sintesi delle precedenti, che specifica che ogni persona ha due genitori ed è più giovane di entrambi:
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>genitori->size()=2 and genitori->forAll(genitore:Persona | età<genitore.età)</code>
 
Il [[quantificatore esistenziale]] è rappresentato dall'operatore <code>->exists<code>. Questo operatore ritorna un valore [[logica booleana|booleano]] (''vero'' o ''falso'') a seconda che nella collezione esista almeno una istanza che soddisfa una certa condizione. La condizione viene espressa facendo riferimento agli attributi e i metodi dell'istanza da selezionare. Nel seguente esempio, si indica che deve esistere un genitore ''il cui'' sesso è maschile, e uno ''il cui'' sesso è femminile.
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>genitori->size()=2 and genitori->exists(sesso=m) and genitori->exists(sesso=f)</code>
 
Riga 46:
L'operatore <code>->includes</code> torna invece un valore booleano a seconda che una certa collezione includa o meno un determinato oggetto, e l'operatore <code>->excludes</code> verifica la condizione opposta. Vi sono poi operatori che rappresentano operazioni insiemistiche, come <code>->union</code> ([[unione]]).
 
:<code><b>'''context</b>''' Persona <b>'''inv:</b>'''<br></code>
:<code>antenati=genitori->union(genitori.antenati->asSet())</code>
 
Riga 55:
OCL consente di descrivere (parzialmente o completamente) la semantica di un'operazione di una classe per mezzo di ''precondizioni'' e ''postcondizioni''. Una precondizione è una condizione che deve essere vera immediatamente prima dell'esecuzione di una operazione (e quindi corrisponde anche a una ''guardia'' in uno [[Statechart Diagram|diagramma degli stati]]). Una postcondizione è una condizione che deve essere vera al termine dell'esecuzione di un'operazione. Precondizioni e postcondizioni sono esprimibili formalmente anche in molti [[linguaggio di programmazione|linguaggi di programmazione]], e possono avere sia funzioni di [[debug]] che concorrere alla semantica del [[programma (informatica)|programma]]: vedi [[asserzioni in Java]].
 
:<code><b>'''context</b>''' Persona::sposa(p:Persona) <b>'''pre:</b>'''<br></code>
:<code>coniuge->size()=0</code>
 
:<code><b>'''context</b>''' Persona::sposa(p:Persona) <b>'''post:</b>'''<br></code>
:<code>coniuge=p and p.coniuge=self</code>
 
Riga 68:
Un'espressione OCL può essere usata anche per descrivere il valore di un attributo derivato di una classe. Per esempio, le seguenti regole specificano chi sono rispettivamente i ''suoceri'' e i ''consuoceri'' di una persona:
 
:<code><b>'''context</b>''' Persona::suoceri:Set(Persona) <b>'''derive:</b>'''<br></code>
:<code>coniuge.genitori</code>
 
:<code><b>'''context</b>''' Persona::consuoceri:Set(Persona) <b>'''derive:</b>'''<br></code>
:<code>figli.coniuge->asSet().genitori->asSet()</code>
 
Estremamente simile a un attributo derivato è una ''query'', ovvero una operazione senza effetti collaterali che fornisce un'informazione sull'oggetto a cui viene applicata. (Da un punto di vista implementativo potrebbe non esistere ''alcuna'' distinzione). La sintassi OCL per descrivere la semantica di un'operazione ''query'' è dunque molto simile a quella per le regole di derivazione. Se <code>suoceri</code> fosse stata espressa come query, la si sarebbe specificata in OCL come segue:
 
:<code><b>'''context</b>''' Persona::suoceri():Set(Persona) <b>'''body:</b>'''<br></code>
:<code>coniuge.genitori</code>
 
Riga 82:
Un'espressione OCL può essere usata anche per descrivere il valore iniziale di un attributo:
 
:<code><b>'''context</b>''' Persona::età:Integer <b>'''init:</b>'''<br></code>
:<code>0</code>
 
Riga 88:
I vincoli OCL possono essere corredati di altre caratteristiche che non concorrono alla loro semantica ma contribuiscono alla loro [[leggibilità]]. I [[commento|commenti]] sono introdotti dai caratteri <code>--<code>, e si intendono proseguire fino alla fine della linea. I vincoli possono essere dotati di un nome, composto da una singola parola (senza spazi) posta dopo la parola chiave <code>inv</code>, <code>pre</code> ecc:
 
:<code><b>'''context</b>''' Persona::sposa(p:Persona) <b>pre<b> monogamia:<br></code>
:<code>coniuge->size()=0</code>