Object Constraint Language: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Funzionalità collegamenti suggeriti: 2 collegamenti inseriti.
 
(43 versioni intermedie di 24 utenti non mostrate)
Riga 1:
L''''Object Constraint Language''' 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|calcolo dei predicati del primo ordine]] per l'espressione di condizioni logiche inerenti loallo stato e lealle operazioni di oggetti in un contesto ''object-oriented''. Con la potenza del calcolo dei predicati, OCL consente di descrivere [[invarianteInvariante di classe|invarianti]] che legano il valore degli attributi di una classe, [[asserzione (informatica)|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 (informatica)|effetti collaterali]].
 
Gran parte delle informazioni che si possono descrivere in OCL non sono esprimibili in nessun altro modo ''formale'' nel contesto di UML (ovvero non possono essere rappresentate dai [[diagramma|diagrammi]] UML).
 
== Descrizione ==
=== Invarianti semplici ===
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 tornatirestituiti delledalle operazioni, e così via. Nel seguente esempio compare un'espressione che fa riferimento a un attributo:
 
:<code>'''context''' Persona '''inv:'''<br /></code>
:<code>età>=0</code>
 
La [[parola chiave]] <code>context</code> precede la dichiarazione della classe a cui questa regola OCL si applica. <code>inv:</code> specifica che questa particolare regola è una [[un'invariante]], ovvero deve essere interpretata come una condizione che è sempre vera, per tutti gli oggetti di classe <code>Persona</code>. L'espressione che segue dichiara che l'età di una persona è sempre non negativa.
 
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>'''context''' Persona '''inv:'''<br /></code>
:<code>età>=0 and età<padre.età</code>
 
Questa regola arricchisce la precedente con un ulteriore vincolo (legato da un [[Algebra_di_BooleAlgebra di Boole#AND|"AND" booleano]]), che specifica, inoltre, che ogni persona è più giovane del proprio padre.
 
=== Invarianti su collezioni ===
Gli attributi con molteplicità maggiore di 1 (ovvero che rappresentano [[insieme|insiemi]]), detti ''collezioni'', possono essere manipolati in OCL con un insieme di [[operatore (informatica)|operatori]] specifici. Anche un attributo con molteplicità 1 ma trattato come collezione può essere manipolato con i seguenti operatori.
 
L'operatore <code>->size()</code> fornisce la numerosità di una collezione. La seguente regola indica che ogni persona ha due genitori:
 
:<code>'''context''' Persona '''inv:'''<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>'''context''' Persona '''inv:'''<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 un'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>'''context''' Persona '''inv:'''<br /></code>
:<code>genitori->size()=2 and genitori->exists(sesso=m) and genitori->exists(sesso=f)</code>
 
Riga 42:
 
:<code>collezione->exists(condizione)</code>
:<code>collezione->select(condizione)->size()>0</code>
 
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 (insiemistica)|unione]]).
 
:<code>'''context''' Persona '''inv:'''<br /></code>
:<code>antenati=genitori->union(genitori.antenati->asSet())</code>
 
Quest'ultimo vincolo mostra come OCL consenta una un'applicazione insolita della dot notation della forma ''<nowiki><collezione>.<attributo></nowiki>''; questa espressione ritorna l'insieme dei valori che l'attributo specificato assume nei vari elementi della collezione. Nel caso <code>genitori.antenati</code> si tratterebbe di un insieme di insiemi. Per ricondurlo a un insieme semplice, viene usato l'operatore <code>->asSet</code>.
 
=== Precondizioni e postcondizioni ===
 
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 un'operazione (e quindi corrisponde anche a una ''guardia'' in un [[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>'''context''' Persona::sposa(p:Persona) '''pre:'''<br /></code>
:<code>coniuge->size()=0</code>
 
:<code>'''context''' Persona::sposa(p:Persona) '''post:'''<br /></code>
:<code>coniuge=p and p.coniuge=self</code>
 
Nell'indicazione del contesto di questi due vincoli viene indicata una specifica operazione della classe Persona, per la quale si indica che una precondizione (introdotta dalla parola chiave <code>pre</code>) per l'operazione di sposare una persona <code>p</code> è non essere sposati (la "numerosità" dell'attributo <code>coniuge</code> dev'essere 0; in molti linguaggi questo si esprimerebbe dicendo che <code>coniuge</code> è ''[[null]]''). La postcondizione (<code>post</code> è che <code>p</code> diventerà il mio coniuge e io (identificato dalla parola chiave <code>self</code>, che corrisponde al <code>this</code> di molti linguaggi) sono il coniuge della persona che ho sposato.
 
Nelle espressioni per le postcondizioni si possono usare alcuni simboli speciali dedicati. La parola chiave <code>result</code> indica il valore tornato dall'operazione. Il simbolo <code>@pre</code>, applicato al nome di un attributo, si riferisce al valore che l'attributo aveva ''prima'' che fosse eseguita l'operazione.
 
=== Regole di derivazione e query ===
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>'''context''' Persona::suoceri:Set(Persona) '''derive:'''<br /></code>
:<code>coniuge.genitori</code>
 
:<code>'''context''' Persona::consuoceri:Set(Persona) '''derive:'''<br /></code>
:<code>figli.coniuge->asSet().genitori->asSet()</code>
 
Estremamente simile a un attributo derivato è una ''query'', ovvero una un'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>'''context''' Persona::suoceri():Set(Persona) '''body:'''<br /></code>
:<code>coniuge.genitori</code>
 
=== Valori iniziali di attributi ===
Un'espressione OCL può essere usata anche per descrivere il valore iniziale di un attributo:
 
:<code>'''context''' Persona::età:Integer '''init:'''<br /></code>
:<code>0</code>
 
=== Informazioni aggiuntive ===
I vincoli OCL possono essere corredati di altre caratteristiche che non concorrono alla loro semantica ma contribuiscono alla loro [[leggibilità]]. I [[commento (informatica)|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>'''context''' Persona::sposa(p:Persona) <b>pre</b> monogamia:<br /></code>
:<code>coniuge->size()=0</code>
 
=== Tipi e operatori predefiniti ===
Le espressioni OCL possono contenere riferimenti a quattro [[tipo primitivo|tipi primitivi]], definiti anche per UML: <code>Integer</code> ([[numeri interi]]), <code>Real</code> ([[numeri reali]]), <code>String</code> ([[stringa (informatica)|stringhe]]), <code>Boolean</code> (valori [[algebra di Boole|booleani]]). Su tali tipi primitivi sono definiti un vasto assortimento di operatori.
 
I seguenti operatori si applicano ai tipi numerici Integer e Real:
{| class="wikitable"
{| border=1
|! '''Significato'''
|! '''Sintassi'''
|! '''Tipo valore tornato'''
|-
| uguaglianza
Riga 151:
| a'''.abs'''
| Integer o Real
|-
| disuguaglianza
| a'''<>'''b
| Boolean
|-
| massimo
Line 174 ⟶ 170:
 
I seguenti operatori si applicano al tipo Boolean:
{| class="wikitable"
{| border=1
|! '''Significato'''
|! '''Sintassi'''
|! '''Tipo valore tornato'''
|-
| or logico (OR)
Line 214 ⟶ 210:
I seguenti operatori si applicano al tipo String:
 
{| class="wikitable"
{| border=1
|! '''Significato'''
|! '''Sintassi'''
|! '''Tipo valore tornato'''
|-
| concatenazione
Line 238 ⟶ 234:
| a'''.substring('''n, m''')'''
| String
|-
| esistenza carattere all'interno della stringa (da A a Z)
| a'''.exists('''c ┃ c = [A, ..., Z]''')'''
| Boolean
|-
| uguaglianza
Riga 248:
|}
 
== Tool ==
La maggior parte dei tool e degli [[Integrated development environment|ambienti integrati]] per la modellazione in UML non gestiscono ancora OCL, o lo gestiscono in modo solo parziale. Molti dei tool elencati qui di seguito non sono integrati in ambienti di modellazione UML.
 
* [[Model Run]] ([[Borland]], {{collegamento interrotto|1=[http://www.borland.com/company/boldsoft.html/products/modelrun/modelrun.html] |data=marzo 2018 |bot=InternetArchiveBot }}), attualmente incluso in [[Borland Delphi 7 Studio Architect]]
* [[OCL Compiler]] ([[Cybernetic Intelligence GMBH]], [https://web.archive.org/web/20191227145653/http://www.cybernetic.org/]), un analizzatore di espressioni OCL, con diversi front-end per l'integrazione in ambienti UML come [[Rational Rose]]
* [[OCLCUD]] ([[Università tecnica di Dresda|Università di [[Dresda]]), [http://dresden-ocl.sourceforge.net]), integrato con [[ArgoUML]]
* [[Octopus]] ([[Klasse Objecten]], [http://www.klasse.nl/ocl/octopus-intro.html] {{Webarchive|url=https://web.archive.org/web/20050208013427/http://www.klasse.nl/ocl/octopus-intro.html |data=8 febbraio 2005 }}). Supporta completamente l'ultima versione di OCL, 2.0. Creato dagli autori di OCL.
 
==Voci correlateCuriosità ==
* Il linguaggio [[Eiffel (linguaggio)|Eiffel]] fu uno dei primi [[linguaggio di programmazione|linguaggi]] [[Programmazione orientata agli oggetti|object-oriented]] a includere un sottolinguaggio dichiarativo per esprimere [[asserzione (informatica)|asserzioni]]
 
* IlAnche [[EiffelJava (linguaggio)|linguaggio Eiffel]] fu uno dei primi [[linguaggio di programmazione)|linguaggiJava]] [[Programmazioneha orientataun agli oggetti|object-oriented]] a includere unproprio sottolinguaggio dichiarativo per esprimerele [[asserzione (Java)|asserzioni]]
* [[Syntropy]], [[Catalysis]] e [[BON]] sono altri linguaggi che consentono di esprimere vincoli su sistemi a oggetti
* Anche [[Java (linguaggio)|Java]] ha un proprio sottolinguaggio per le [[asserzione (Java)|asserzioni]]
* [[Syntropy]], [[Catalysis]] e [[BON]] sono altri linguaggi che consentono di esprimere vincoli su sistemi a oggetti
* L'uso di precondizioni, postcondizioni e invarianti come strumenti di specifica di dati e operazioni ha origine negli studi sulla [[semantica assiomatica]] di [[C.A.R. Hoare]] e [[Edsger Dijkstra]].
 
== Bibliografia ==
* [[Jos B. Warmer]], [[Anneke G. Kleppe]]. ''[[The Object Constraint Language: Precise Modeling with UML]]'' ([[Addison-Wesley]] [[Object Technology Series]] [[1998]]), ISBN 02013794060-201-37940-6
 
== Collegamenti esterni ==
* [[Jos B. Warmer]], [[Anneke G. Kleppe]]. ''[[The Object Constraint Language: Precise Modeling with UML]]'' ([[Addison-Wesley]] [[Object Technology Series]] [[1998]]), ISBN 0201379406
* [https://web.archive.org/web/20110807045309/http://www.omg.org/technology/documents/modeling_spec_catalog.htm#UML Specifiche di UML] (includono la specifica di OCL)
* [https://web.archive.org/web/20060220003552/http://www.parlezuml.com/tutorials/umlforjava/java_ocl.pdf Tutorial su OCL per [[Java (linguaggio)|Java]]], con informazioni molto complete sulla sintassi OCL
* [http://www.klasse.nl/ocl/index.html Varie risorse su OCL] {{Webarchive|url=https://web.archive.org/web/20060515052915/http://www.klasse.nl/ocl/index.html |data=15 maggio 2006 }} nel sito di [[Jos Warmer]] e [[Anneke Kleppe]], ideatori di OCL
* {{cita web | 1 = http://www.deepthought.com.au/it/ocl_review.html | 2 = Una revisione critica di OCL | accesso = 5 maggio 2006 | urlarchivio = https://web.archive.org/web/20060505175435/http://www.deepthought.com.au/it/ocl_review.html | dataarchivio = 5 maggio 2006 | urlmorto = sì }}
* {{cita web | 1 = http://projekte.fast.de/Projekte/forsoft/ocl/4_1Equivalence_OCL_relation.html | 2 = Confronto fra OCL e calcolo relazionale | accesso = 7 maggio 2006 | urlarchivio = https://web.archive.org/web/20070313123733/http://projekte.fast.de/Projekte/forsoft/ocl/4_1Equivalence_OCL_relation.html | dataarchivio = 13 marzo 2007 | urlmorto = sì }}
 
{{Linguaggi di interrogazione}}
==Collegamenti esterni==
 
* [http://www.omg.org/technology/documents/modeling_spec_catalog.htm#UML Specifiche di UML] (includono la specifica di OCL)
* [http://www.parlezuml.com/tutorials/umlforjava/java_ocl.pdf Tutorial su OCL per [[Java (linguaggio)|Java]]], con informazioni molto complete sulla sintassi OCL
* [http://www.klasse.nl/ocl/index.html Varie risorse su OCL] nel sito di [[Jos Warmer]] e [[Anneke Kleppe]], ideatori di OCL
* [http://www.deepthought.com.au/it/ocl_review.html Una revisione critica di OCL]
* [http://projekte.fast.de/Projekte/forsoft/ocl/4_1Equivalence_OCL_relation.html Confronto fra OCL e calcolo relazionale]
 
[[Categoria:UML]]
[[Categoria:LinguaggiTeoria dei linguaggi formali]]
 
[[de:Object Constraint Language]]
[[en:Object Constraint Language]]
[[es:Lenguaje de especificación OCL2.0]]
[[fr:Object Constraint Language]]
[[ja:Object Constraint Language]]
[[lt:Object Constraint Language]]
[[pt:OCL]]