Trong biểu đồ UML, một sơ đồ như sơ đồ lớp chẳng hạn, không đủ để đặc tả tất cả các khía cạnh liên quan. Các ràng buộc liên quan đến các đối tượng trong sơ đồ cần được mô tả chính xác và đầy đủ. Các ràng buộc này thường được mô tả bằng ngôn ngữ tự nhiên. Thực tế đã chỉ ra rằng việc mô tả các ràng buộc bằng ngôn ngữ tự nhiên dẫn đến sự nhập nhằng và cần một ngôn ngữ hình thức để mô tả sao cho cả những người không có kiến thức toán học tốt cũng có thể dễ dàng hiểu được. Ngôn ngữ ràng đối tượng (Object Constraint Language – OCL) đã được phát triển để thực hiện mục tiêu trên. Nó đã được phát triển như là một ngôn ngữ mô hình hóa kinh doanh bên trong phân khu bảo hiểm của IBM, có tiền thân từ phương pháp Syntropy [7].
OCL là một ngôn ngữ đặc tả thuần túy, do đó một biểu thức OCL được đảm bảo không có hiệu ứng phụ. Khi một biểu thức OCL được định giá, nó trả lại một giá trị. Nó không thể thay đổi bất kỳ thứ gì trong mô hình. Điều này có nghĩa là trạng thái của hệ thống sẽ không bao giờ thay đổi vì sự định giá của các biểu thức OCL, thậm chí một biểu thức OCL có thể được sử dụng để đặc tả một thay đổi trạng thái (ví dụ trong một post-condition).
OCL không phải là một ngôn ngữ lập trình, vì thế không thể viết lôgic chương trình hay điều khiển luồng trong OCL. Không thể gọi các tiến trình hay kích hoạt các thao tác phi truy vấn trong OCL. Vì vị trí ban đầu của OCL là một ngôn ngữ mô hình hóa nên các biểu thức OCL không được khai báo để thực thi trực tiếp.
OCL là một ngôn ngữ định kiểu, do vậy mỗi biểu thức OCL có một kiểu. Một biểu thức OCL phải tuân theo các luật tương thích kiểu của ngôn ngữ. Ví dụ, không thể so sánh một kiểu Integer với một kiểu String. Sự định giá của một biểu thức OCL là tức thời. Điều này có nghĩa là các trạng thái của các đối tượng trong một mô hình không thể thay đổi trong quá trình định giá.
OCL được dùng với nhiều mục đích khác nhau. Chương này tập chung vào kiểm chứng bất biến của các lớp. Do vậy, phần này tập trung vào mô tả bất biến của các lớp được biểu diễn trong OCL như thế nào.
3.3.1. Biểu diễn biểu thức OCL
Một giàng buộc được thể hiện bởi OCL dưới dạng các biểu thức khi được định giá sẽ cho giá trị đúng (true) hoặc sai (false). Mọi ràng buộc chắc chắn phải thuộc về một kiểu cụ thể (lớp, lớp liên kết và giao diện). Một lớp mà bất biến được đặt vào được gọi là ngữ cảnh bất biến (invariant context). Ngữ cảnh có thể được xác định bởi:
Context <tên ngữ cảnh>
Các từ khóa inv, pre và post chỉ ra các mẫu (stereotype) tương ứng là «invariant» - bất biến, «precondition» - điều kiện trước và «postcondition» - điều kiện sau của ràng buộc. Các biểu thức OCL chỉ được sử dụng các ký tự ASCII.
Ví dụ về việc biểu diễn ràng buộc trên sơ đồ UML:
+earnMoney(int amount)() : int +spendMoney(int amount)() : int +Age : int +amountAvailable : int Employee «precondition» {amount >= 10} «invariant»
{age >= 18 and age <=60}
«postcondition»
{amountAvailable>=0 and result >=10}
Hình 3.1. Biểu diễn các ràng buộc trên sơ đồ UML và bằng các biểu thức OCL:
context Employee
inv correctAge: self.Age >=18 and Self.Age <=60
context Employee:: spendMoney(amount: integer): integer pre allowedAmount: amount >=10
post amountAvailable >=0 and result >=10
Trong ngữ cảnh ngày, từ khóa context định nghĩa một ngữ cảnh cho lớp có tên kèm sau. Từ khóa inv hoặc invariant cho phép định nghĩa ràng buộc cho lớp là tuổi của nhân viên phải luôn lớn hơn hoặc bằng 10 và nhỏ hơn hoặc bằng 60. Từ khóa pre định nghĩa tiền điều kiện cho phương thức spendMoney là số tiền mỗi lần tiêu phải luôn lớn hơn hoặc bằng $10 và từ khóa post định nghĩa hậu điều kiện là số hiện có phải luôn lớn hơn 0 và số tiền tiêu được phải lớn hơn $10.
3.3.2. Bất biến (invariant)
Bất biến của lớp (class invariant) là ràng buộc phải luôn luôn được thỏa đối với tất cả các thể hiện của lớp. Trong sơ đồ UML, bất biến là ràng buộc có stereotype là «invariant». Trong biểu thức OCL, bất biến là biểu thức logic được biểu diễn sau từ khóa inv hay invariant.
Giả sử chúng ta có lớp biểu diễn các cầu thủ là Player và mọi cầu thủ tham gia phải có tuổi lớn hơn hoặc bằng 16 thì thuộc tính age thể hiện tuổi của cầu thủ phải có giá trị luôn luôn lớn hơn hay bằng 16. Ràng buộc này được thể hiện trong OCL như sau:
inv: self.age >=16
Trong đó Player là kiểu của thể hiện theo ngữ cảnh của một biểu thức OCL được viết sau từ khóa context. Từ khóa inv khai báo một ràng buộc là một «invariant». self là một thể hiện của Player. Đa số các trường hợp ngữ cảnh là rõ ràng và ta có thể bỏ self.
inv: age >=16
Một ràng buộc có thể có tên được đặt sau từ khóa inv nhưng không bắt buộc. Trong ví dụ trên, có thể đặt tên cho ràng buộc là playerAge.
inv playerAge: self.age >=16
Ta cũng có thể gán một tên tường minh cho một ngữ cảnh thay thế cho self như sau:
Context p: Player inv: p.age >=16
Các bất biến có thể được thể hiện độc lập hoặc được nối với nhau bằng từ toán tử and. Ví dụ, tuổi của cầu thử được giới hạn từ 16 đến 35 thì bất biến được thể hiện:
Context p: Player
inv: p.age >=16 and p.age <=35
hoặc
Context p: Player inv: p.age >=16 inv: p.age <=35
Các biểu thức OCL có thể gọi các phương thức. Ví dụ, số cầu thủ một đội tuyển không được ít hơn 16 và không được vượt quá 20.
context PlayerTeam
inv: self.getSize() >= 16 and self.getSize() <= 20
Các biểu thức OCL có thể duyệt các liên kết. Ví dụ, tuổi của người lãnh đạo đội bóng phải lớn hơn hoặc bằng 40.
context PlayerTeam
inv: self.manager.age >=40
Việc liên kết sẽ tạo ra đối tượng với kiểu tương ứng. Trong ví dụ trên self.manager là một đối tượng có kiểu là Person. Để truy cập tới một liên kết hoặc thuộc tính hay phương thức của nó ta sử dụng mũi tên „->‟ hoặc dấu chấm.
Trong trường hợp trên bội của liên kết là 1. Khi bội của liên kết lớn hơn 1 thì các thao tác trên tập hợp sẽ được sử dụng như size, includes, isEmpty, union, intersection, … Ví dụ:
context PlayerTeam inv: player->size()<20