OCL का UML में उपयोग करने का व्यापक मार्गदर्शिका, PlantUML उदाहरणों के साथ
परिचय

जबकि UML (संयुक्त मॉडलिंग भाषा) एक प्रणाली के संरचना के दृश्यात्मक चित्रण के लिए अत्यंत उत्कृष्ट है, लेकिन जटिल व्यावसायिक नियम और अर्थको व्यक्त करने की सटीकता की कमी है। यहीं पर वस्तु सीमा भाषा (OCL) आता है। OCL औपचारिक “चिपकाव” के रूप में कार्य करता है जो UML आरेखों को कठोर, अस्पष्ट नहीं व्यावसायिक तर्क से जोड़ता है।
यह मार्गदर्शिका बताती है कि OCL UML के साथ कैसे एकीकृत होता है, आपको जानने की आवश्यकता होने वाली मुख्य अवधारणाएं, और प्रायोगिक PlantUML उदाहरण प्रदान करती है जो इन सीमाओं को दृश्य रूप से दिखाते हैं।
1. सहयोग: OCL द्वारा UML का पूरक होना
UML को अपनी प्रणाली की ‘हड्डी’ (क्लास, संबंध, अवस्थाएं) के रूप में सोचें और OCL को ‘तंत्रिका तंत्र’ (नियम, शर्तें और तर्क) के रूप में सोचें जो हड्डी के व्यवहार को नियंत्रित करते हैं।
UML में दृश्य प्रतिनिधित्व
मानक UML में, OCL सीमाओं को आमतौर पर नोट्स संबंधित मॉडल तत्वों (क्लास, ऑपरेशन या अवस्थाओं) से जुड़े होते हैं।
-
स्टेरियोटाइप:अक्सर, OCL युक्त नोट्स को दिया जाता है
{सीमा}स्टेरियोटाइप। -
संदर्भ:प्रत्येक OCL अभिव्यक्ति के साथ शुरू होती है
संदर्भकीवर्ड, जो बताता है कि नियम किस UML तत्व पर लागू होता है।
2. UML में OCL की मुख्य अवधारणाएँ
A. क्लास अनिवार्यताएँ (अनिवार्यता)
अनिवार्यताएँ ऐसी स्थितियाँ हैं जो आवश्यक हैंहमेशा सत्य होना चाहिएक्लास के प्रत्येक उदाहरण के लिए, चाहे किसी भी ऑपरेशन को कॉल किया जाए या नहीं।
मुख्य अवधारणा:यदि एक अनिवार्यता का उल्लंघन होता है, तो प्रणाली एक अमान्य स्थिति में है।

@startuml
skinparam classAttributeIconSize 0
skinparam noteBackgroundColor #FFF9C4
class BankAccount {
- accountNumber: String
- balance: Real
- isOverdraftEnabled: Boolean
+ withdraw(amount: Real)
+ deposit(amount: Real)
}
note right of BankAccount
**क्लास अनिवार्यताएँ:**
context BankAccount
-- बैलेंस कभी भी ऋणात्मक नहीं हो सकता जब तक कि ओवरड्राफ्ट सक्षम न हो
inv balanceRule:
self.balance >= 0 या self.isOverdraftEnabled
-- ओवरड्राफ्ट सीमा 500 से अधिक नहीं हो सकती
inv overdraftLimit:
self.isOverdraftEnabled implies self.balance >= -500
end note
@enduml
B. ऑपरेशन अनुबंध (पूर्व, पश्चात, शरीर)
ऑपरेशन (विधियाँ) को ऐसी सीमाएँ हो सकती हैं जो उनके क्रियान्वयन से पहले और बाद में व्यवहार को परिभाषित करती हैं।
-
पूर्व-शर्त (
पूर्व): वह क्या होना चाहिए जो सच होना चाहिए पहले ऑपरेशन शुरू होने से पहले। (कॉलर की जिम्मेदारी)। -
पोस्ट-शर्त (
पोस्ट): वह क्या होगा जो सच होगा बाद में ऑपरेशन पूरा होने के बाद। (ऑपरेशन की गारंटी)। -
बॉडी (
बॉडी): क्वेरी ऑपरेशन के लिए निर्दिष्ट रिटर्न मान को परिभाषित करता है।

@startuml
skinparam classAttributeIconSize 0
skinparam noteBackgroundColor #E8F5E9
class ShoppingCart {
- items: Bag<Product>
- totalAmount: Real
+ checkout(): Receipt
+ getTotal(): Real
}
note right of ShoppingCart
**ऑपरेशन कॉन्ट्रैक्ट्स:**
-- प्री-शर्त: कार्ट खाली नहीं होना चाहिए
context ShoppingCart::checkout(): Receipt
pre: self.items->notEmpty()
-- पोस्ट-शर्त: कार्ट खाली कर दिया गया, रसीद उत्पन्न की गई
post: self.items->isEmpty() and result <> null
-- बॉडी: क्वेरी ऑपरेशन परिभाषा
context ShoppingCart::getTotal(): Real
body: self.items->collect(price)->sum()
end note
@enduml
सी। डेराइव्ड और इनिशियल मान (डेराइव, इनिट)
आवश्यक डेटा स्टोर करने के बजाय, यूएमएल अनुलक्षित को चिह्नित करने की अनुमति देता है {डेराइव्ड} या {इनिशियल}, जहां ओसीएल उनके निर्दिष्ट मान को परिभाषित करता है।

@startuml
skinparam classAttributeIconSize 0
skinparam noteBackgroundColor #E3F2FD
class Employee {
- firstName: String
- birthDate: Date
- {derived} age: Integer
- {initial} isActive: Boolean = true
}
note right of Employee
**व्युत्पन्न और प्रारंभिक मान:**
-- उ возраст की गणना स्वचालित रूप से करें
context Employee::age: Integer
derive: self.birthDate.yearsSinceToday()
-- निर्माण के समय प्रारंभिक अवस्था
context Employee::isActive: Boolean
init: true
end note
@enduml
D. राज्य मशीन गार्ड्स
राज्य मशीन आरेखों में, संक्रमण के पास हो सकता हैगार्ड्स—बूलियन व्यंजक जिनका मूल्यांकन संक्रमण के घटित होने के लिए सत्य होना चाहिए। OCL इन गार्ड्स लिखने की मानक भाषा है।

@startuml
skinparam stateBackgroundColor #F3E5F5
[*] --> Created
Created --> PendingApproval : submit()
state PendingApproval {
}
PendingApproval --> Approved : [total < 10000]
PendingApproval --> Rejected : [total >= 10000]
Approved --> Shipped : ship()
Shipped --> [*]
note right of PendingApproval
**राज्य अविनाशीता:**
context Order
inv: self.status = 'Pending' implies
self.submittedBy->notEmpty()
end note
note right of Approved
**approve() की पश्च-शर्त:**
context Order::approve()
post: self.status = 'Approved' and
self.approvedDate <> null
end note
@enduml
3. व्यापक केस स्टडी: कंपनी मॉडल
आइए OCL को एक जटिल UML क्लास आरेख पर लागू करें जिसमें शामिल हैकर्मचारी, विभाग, औरप्रोजेक्ट. यह दर्शाता है कि OCL संबंधों को कैसे निर्देशित करता है और संग्रह इटरेटर्स का उपयोग करता है (select, forAll, size).

@startuml
skinparam classAttributeIconSize 0
skinparam noteBackgroundColor #FFFDE7
skinparam noteBorderColor #FBC02D
class Employee {
- SSN: String
- firstName: String
- birthDate: Date
- hireDate: Date
- salary: Float
+ age(): Integer
}
class Department {
- number: Integer
- name: String
- locations: Set<String>
- {derived} nbrEmployees: Integer
}
class Project {
- number: Integer
- name: String
- location: String
}
Employee "0..*" -- "1" Department : worksFor > department
Employee "0..*" -- "0..*" Project : worksOn > project
Employee "1" -- "0..1" Department : manages > managedDept
Department "1" -- "0..*" Project : controls > projects
Employee "1" -- "0..*" Employee : supervisor > subordinates
note right of Employee
**जटिल अविनाशीता और नेविगेशन:**
context Employee
-- 1. मूल गुण नियम
inv ageCheck: self.age() >= 18
-- 2. संबंधों का नेविगेशन (बहुलता)
inv maxProjects: self.worksOn->size() <= 4
-- 3. इटरेटर्स का उपयोग (forAll)
-- प्रबंधक को अधीनस्थों से पहले नियुक्त किया जाना चाहिए
inv hireOrder: self.subordinates->forAll(
sub | sub.hireDate > self.hireDate
)
-- 4. क्रॉस-संबंध नियम
-- कर्मचारी केवल उन प्रोजेक्ट्स पर काम कर सकता है जिन पर उनके विभाग का नियंत्रण हो
inv projectControl:
self.worksFor.controls->includesAll(self.worksOn)
-- 5. अद्वितीय पहचानकर्ता (की)
inv uniqueSSN: Employee.allInstances()->forAll(e1, e2 |
e1 <> e2 implies e1.SSN <> e2.SSN
)
end note
note bottom of Department
**व्युत्पन्न गुण:**
context Department::nbrEmployees: Integer
derive: self.worksFor->size()
end note
note right of Project
**प्रोजेक्ट अविनाशीता:**
context Project
-- प्रोजेक्ट स्थान विभाग के स्थानों में से एक होना चाहिए
inv validLocation:
self.controls.locations->includes(self.location)
end note
@enduml
4. UML में उन्नत OCL तकनीकें
A. उपयोग करनाletपठनीयता के लिए
जब एक OCL अभिव्यक्ति बहुत जटिल हो जाती है, तो उसके भीतर स्थानीय चर परिभाषित करने के लिए letकीवर्ड का उपयोग नियम में स्थानीय चर परिभाषित करने के लिए करें। इससे UML नोट पढ़ने में बहुत आसान हो जाता है।

@startuml
skinparam classAttributeIconSize 0
class Employee {
- worksOn: Set<Project>
}
note right of Employee
**जटिल तर्क के लिए 'let' का उपयोग:**
context Employee
-- कुल घंटे की गणना करें और सीमाओं की जांच करें
inv workingHours:
let totalHours: Integer =
self.worksOn->collect(hours)->sum()
in totalHours >= 30 और totalHours <= 50
end note
@enduml
बी। पोस्ट-शर्तों में पिछले मानों का प्रबंधन (@pre)
जब एक पोस्ट-शर्त परिभाषित करते हैं, तो आपको अक्सर नया अवस्था के साथ पुराना अवस्था की तुलना करने की आवश्यकता होती है। OCL @pre पोस्टफिक्स का उपयोग एक गुण के मान तक पहुंचने के लिए करता है, जैसा कि क्रियान्वयन शुरू होने से पहले था।

@startuml
skinparam classAttributeIconSize 0
class Company {
- employees: Set<Employee>
+ hireEmployee(p: Employee)
}
note right of Company
**पोस्ट-शर्तों में @pre का उपयोग:**
context Company::hireEmployee(p: Employee)
-- नए कर्मचारी सेट पुराने सेट + नए व्यक्ति है
post: self.employees = self.employees@pre->including(p)
end note
@enduml
5. UML में OCL के लिए सर्वोत्तम प्रथाएं
-
अपनी सीमाओं के नाम रखें: हमेशा अपने अनिवार्यताओं और शर्तों का नाम दें (उदाहरण के लिए
inv maxProjects:)। इससे दस्तावेज़ीकरण या ट्रेसेबिलिटी मैट्रिक्स में उन्हें संदर्भित करना आसान हो जाता है। -
नोट्स का रणनीतिक रूप से उपयोग करें: PlantUML और दृश्य UML उपकरणों में, OCL के साथ क्लास बॉक्स को भर न दें। OCL को पड़ोसी नोट्स में रखें। इससे आरेख साफ और पठनीय रहता है।
-
अति सीमाबद्धता न करें: केवल उन नियमों के लिए OCL लिखें जिन्हें UML बहुलता (उदाहरण के लिए
0..1,1..*) या मूलभूत प्रकारों द्वारा आसानी से व्यक्त नहीं किया जा सकता है। यदि कोई नियम दृश्य रूप से दर्शाया जा सकता है, तो उसे दृश्य रूप से दर्शाएं। -
संग्रह इटरेटर का लाभ उठाएं: मास्टर
->select(),->forAll(),->exists(), और->collect(). वे OCL में UML संबंधों को नैविगेट करने के लिए सबसे शक्तिशाली उपकरण हैं। -
नल/खाली सेट की जांच करें: जब वैकल्पिक संबंधों (बहुलता
0..1या0..*), हमेशा->notEmpty()या->isEmpty()गुणों तक पहुंचने से पहले अपरिभाषित मूल्यांकन त्रुटियों से बचने के लिए उपयोग करें।
निष्कर्ष
यह पोस्ट Deutsche, English, Español, فارسی, Français, Bahasa Indonesia, 日本語, Polski, Portuguese, Ру́сский, Việt Nam, 简体中文 और 繁體中文 में भी उपलब्ध है।














