·
הקדמה
הקדמה
ראשי התיבות של UML
הם: Unified Modeling Language. זוהי שפה (בעיקרה גראפית) אשר מיועדת, בעיקרה, לתיאור מערכת.
לאחרונה, UML
עברה תהליך של סטנדרטיזציה על ידי OMG (Object Management Group)
וכיום כבר קיימת ל-UML גרסה מספר 1.3. נספח זה כולל את אותם חלקיה של UML
אשר רלוונטיים לפיתוח ב-Java.
אחת הסיבות העיקריות שבשלן כדאי להשתמש ב-UML
היא שיפור תהליך התקשורת בין אנשי הפיתוח. לעתים, הסברים מילוליים אינם מדויקים
דיים. מנגד, לעתים הצגת קוד מקור כחלק מהסברים והעברת מסרים בין אנשי הפיתוח איננה
מדגישה את העיקר ומרוב עצים לא רואים את היער. שימוש ב-UML מדויק יותר מהסברים מילוליים ועם זאת איננו מרובה בפרטים אשר
מקשים על הבנת עיקר המסר (כפי שקורה כאשר מציגים אחד לשני קוד מקור לשם העברת
מסרים ורעיונות).
לאחר קריאת נספח זה, מומלץ לעבור לנספח
הבא אשר מהווה הכרות ראשונית עם Design
Patterns. הבנה וידע בנושא Design Patterns
מהווים את השלב הבא לאחר הבנת כללי התחביר של שפת תכנות ו/או אופן השימוש ב-UML.
ה-Design Patterns מהווים סדרה של פתרונות לבעיות תכנות
שכיחות. פתרונות אלה ניתן לתאר באמצעות UML בשלב התכנון והעיצוב.
ל-UML מספר חלקים (טכניקות). חלקים אלה יתוארו בחלקיו השונים של נספח
זה. כיוון שחשתי בקושי רב בתרגום המושגים השונים מאנגלית לעברית, עשיתי שימוש במושגים
כפי שהם מופיעים באנגלית.
כדי להבין מהם Use
Cases יש להבין, תחילה,
את המושג Scenario.
Scenario
הוא סדרה של פעולות אשר מתרחשת בין המשתמש לבין המערכת עצמה.
כך למשל,
ניתן לומר על תהליך הרכישה של ספר ב-www.amazon.com כי
הוא מהווה Scenario.
סדרת הפעולות אשר מתבצעות במהלך Scenario זה הן:
1. הלקוח בוחר בספרים שאותם
הוא רוצה לקנות ומוסיף אותם לסל הקניות.
2. כאשר הוא רוצה לשלם ובזאת
לסיים את רכישת הספרים הוא מקיש על הכפתור המתאים וממלא את הפרטים אשר מתארים את
אופן ביצוע המשלוח, פרטי כרטיס האשראי שלו ומאשר באופן סופי את הרכישה.
3. המערכת בודקת את הפרטים
שהלקוח סיפק (בין היתר בודקת גם את פרטיו של כרטיס האשראי) ומאשרת (או לא מאשרת)
את העיסקה.
4. המערכת שולחת ללקוח email
אשר מודיע לו כי העסקה אושרה(או לא אושרה).
5. המערכת מיידעת מערכות
אחרות בארגון בנוגע לפעולות שעליהן לבצע (מעדכנת את מערכת המלאי, מערכת הכספים
וכדומה...).
ה-Scenario שתואר עשוי/עלול לגרום להפעלתו של Scenario
אחר. כך למשל, אם העיסקה לא אושרה (כרטיס אשראי מזויף, למשל) אז
יתחיל להתבצע Scenario
אחר אשר יכלול סדרת פעולות כגון עדכון מערכות אחרות (משטרה למשל...).
Use Case היא קבוצה של Scenarios אשר קשורים ביניהם במטרה סופית משותפת.
אחד הפורמטים המקובלים בתיאורו של Use Case
באופן טקסטואלי הוא תיאור ה-Scenario העיקרי באמצעות
פירוט ומספור סדרת הפעולות אשר כלולות בו, ולאחר מכן, בנפרד, פירוט של האלטרנטיבות
(Other
Scenarions) אשר עשויות/עלולות
להתרחש במידה שה-Scenario
העיקרי לא מתבצע בשלמותו.
כך, למשל, לתהליך רכישתו של ספר בחנות
המקוונת www.amazon.com
ניתן להתייחס כאל Use Case
שניתן לתיאור באופן הבא:
שם ה-Use
Case: רכישת ספר ב-AMAZON:
תנאי קדם להתחלתו של ה-Use Case
הלקוח גולש באתר של AMAZON
ועבר תהליך זיהוי באמצעות cookies.
תיאור ה-Use
Case
1. הלקוח בוחר בספרים שאותם
הוא רוצה לקנות ומוסיף אותם לסל הקניות.
2. כאשר הוא רוצה לשלם ובזאת
לסיים את רכישת הספרים הוא מקיש על הכפתור המתאים וממלא את הפרטים אשר מתארים את
אופן ביצוע המשלוח, פרטי כרטיס האשראי שלו ומאשר באופן סופי את הרכישה.
3. המערכת בודקת את הפרטים
שהלקוח סיפק (בין היתר בודקת גם את פרטיו של כרטיס האשראי) ומאשרת את העיסקה.
4. המערכת שולחת ללקוח email
אשר מודיע לו כי העסקה אושרה.
5. המערכת מיידעת מערכות
אחרות בארגון בנוגע לפעולות שעליהן לבצע (מעדכנת את מערכת המלאי, מערכת הכספים
וכדומה...).
אלטרנטיבה בגין בעיה עם כרטיס האשראי
בצעד מספר 3 המערכת לא מאשרת את העיסקה
בגלל בעיה עם כרטיס האשראי. במקרה כזה, המערכת מאפשרת ללקוח להכניס את פרטיו מחדש
ולנסות שוב.
אלטרנטיבה כאשר מדובר בלקוח שהמערכת כבר
מכירה (לקוח חוזר)
בצעד מספר 2, כאשר הלקוח ניגש למלא את
פרטיו, המערכת מציגה בפניו את פרטיו כפי שאלה ידועים לה מקניותיו הקודמות. הלקוח
יכול לאשר פרטים אלה או למלאם מחדש. לאחר מילוי הפרטים או אישור הפרטים הקיימים
המערכת ממשיכה לפעול בצעד 3.
תנאי הקדם שחייב להתקיים לפני שה-Use Case יתחיל קרוי בלעז בשם: Percondition.
את ה-Use
Case ניתן גם לתאר באופן
גראפי. כדי להבין כיצד יש לעשות זאת, יש, תחילה, להכיר את המושג: Actors. ה-Actor הוא תפקיד שהמשתמש יכול למלא. יש להבחין בין משתמש לתפקיד שהוא
יכול למלא. כך, למשל, באתר הקניות www.amazon.com ניתן להניח כי משתמשיו, פרט לגולשים שמבקרים אותו, כוללים גם את
העובדים של חברת amazon.com.
העובדים ב-amazon.com
כוללים, בין היתר, את המחסנאים ואת מנהל המחסן. האדם שמשמש כמנהל המחסן יכול לפנות
למערכת תחת שני כובעים שונים (שני Actors שונים). הוא יכול
לפנות בתור מנהל המחסן ובכך לקבל
דוחות שמחסנאים פשוטים לא יכולים וגם לא רשאים לקבל אך הוא יכול גם לפנות למערכת
ולהפעילה בתור מחסנאי פשוט ובכך לקבל את ההרשאה לעדכן כמויות במלאי. זוהי, למעשה,
דוגמא להבחנה שניתן לעשות בין שני תפקידים שונים שאותו אדם יכול למלא. כל תפקיד
ייקרא Actor.
ה-Actors הם אשר מבצעים את ה-Use Cases השונים. Actor מסוים יכול לבצע Use Case אחד או מספר Use Cases שונים. באופן דומה, Use Case נתון ניתן לביצוע על ידי Actor אחד או על ידי מספר Actors שונים.
בעת ניתוח המערכת, מומלץ לקבוע, תחילה, את
ה-Actors
שיהיו בה, ורק לאחר מכן, את ה-Use Cases של כל אחד מן ה-Actors אשר נקבעו.
ה-Actor איננו חייב להיות אדם מסוים. ה-Actor יכול גם להיות מערכת מחשב אחרת.
דוגמא לתרשים אשר מציג Use Case:
בתרשים
זה ה-Actor הוא ה-Customer
וה-Use
Case שאותו ה-Custmoer יכול להפעיל הוא Buying Books.
בין Use Cases
יכולים להתקיים קשרים שונים. כך, למשל, כאשר נתון Use Case שחלק מה-Scenarios
שלו מהווים Use Case
אחר, ניתן לומר כי ה-Use Case
שנתון כולל בתוכו Use Case אחר. קשר זה יקרא include.
נהוג להשתמש בקשר include
בין שני Use Cases
כאשר אחד מהם דומה מאוד לאחר והוא בעצם כולל את אותם Scenarios שהאחר כולל, בתוספת כמה Scenarios
נוספים. השימוש בקשר include שימושי כאשר רוצים לתאר מספר Scenarios אלטרנטיביים.
התרשים הבא מציג שני Use
Cases אשר מקיימים קשרי include עם Use
Case שלישי.
קשר אחר אשר יכול
להתקיים בין שני Use Cases
הוא Generalization. קשר זה מתקיים בין שני Use Cases כאשר האחד כולל את אותם Scenarios
אשר
כלולים ב-Use Case האחר בתוספת מספרScenarios נוספים. גם השימוש
ב-Generalization יכול להוות כלי לתיאור אלטרנטיבות שונות של Use Scenarios. בין שני ה-Use Cases
מתקיים קשר בדומה לקשר של הורשה בין שתי מחלקות. Use Case אחד יורש מ- Use
Case אחר. ה-Use
Case שיורש יכול לכלול Scenarios נוספים, וכמו כן, גם את Scenarios
זהים לאלה שהגיעו בהורשה אך מוגדרים מחדש – Overriding
Scenarios בדומה ל Overriding
Methods.
התרשים
הבא מציג שני Use Cases
שביניהם מתקיים הקשר Generalization.
קשר שלישי אשר יכול
להתקיים בין שני Use Cases
הוא extend. הקשר extend
מתקיים בין שני Use Cases
אם האחד יורש מן השני (דומה ל-Generalization)
אך השני, ה-Use Case
שמוריש, קבע extension points:
scenarios שרק אותם ניתן לשנות בהגדרה מחדש ב-Use Case שיורש. את ה-extension points
מציינים על הקו אשר מחבר את שני ה-Use Cases.
התרשים
הבא מציג שני Use Cases
שהאחד extend מן השני.
כדאי
לעשות את ההבחנה בין Business Use Cases
אשר מתארים את האינטראקציה שקיימת בין הגורמים השונים בעסק ומחוצה לו עם העסק עצמו
לבין System
Use Cases אשר מתארים את האינטראקציה
בין התוכנה למשתמשים בה (אנשים אחרים ומערכות אחרות). לא אחת, ניתן ללמוד רבות על
ה-Actors ועל ה-Use Cases
שיופיעו ב-System Use Cases
מתוך ה-Business
Use Cases.
Class
Diagram מתארת את סוגי
האובייקטים אשר קיימים במערכת ואת הקשרים ביניהם. חלק זה מציג בקצרה את אופן
יצירתו של Class Diagram.
בין שני טיפוסים מתקיים association אם אובייקט מן הטיפוס הראשון מחזיק/קשור במספר אובייקטים מן הסוג
השני. בין אובייקט מטיפוס ShoppingCart מתקיים קשר של association עם אובייקט מטיפוס Book (כל shopping cart
מחזיק בנתוניו של ספר אחד או יותר). כל קשר מסוג association מאופיין בקו אשר מחבר בין התיאור הגרפי של שתי המחלקות. כל אחד
משני קצותיו של הקו יכול לקבל שם, role name. כל אחד משני קצותיו של הקו מקבל שם. שם זה הוא ה-role name
(אם קיים) או שמה של המחלקה שקרובה לאותו קצה קו (שמה של המחלקה יהווה את שמו של
קצה של קו אם role name לא
נקבע). לכל קשר של association יש מאפיין נוסף בשם multiplicity אשר מהווה אינדיקציה למספר האובייקטים (מכל אחד משני הטיפוסים אשר
בקשר) אשר יכולים להשתתף בקשר. ה-multiplicity בא לידי ביטוי גראפי בכל אחד משני קצותיו של הקו באמצעות מספר (1
למשל) , הסימן כוכבית * לתיאור מספר לא מוגבל או תחום (*..1 למשל). בדוגמא הבאה
מוצג קשר של association
בין Order
לבין OrderLine.
קשר זה מתאר את העובדה שבכל הזמנה (מתוארת באמצעות אובייקט מטיפוס Order)
יכולה להיות שורה אחת או יותר. כל שורה מתארת פריט אחר בהזמנה (שם, כמות ומחיר).
כיוון שבקצה הקו שמתאר את ה-association ליד התיאור הגרפי של המחלקה Order מופיע 1 זה אומר כי כל אובייקט מטיפוס OrderLine מחובר לאובייקט אחד מטיפוס Order בלבד (לא יותר ולא פחות). כיוון שליד קצה הקו שמתאר את ה-association
ושנמצא ליד תיאורה הגרפי של המחלקה OrderLine מופיע 99..0 זה אומר כי לכל אובייקט מטיפוס Order או שלא מחובר אף אובייקט מטיפוס OrderLine או שמחובר אובייקט אחד (או יותר, עד 99) מטיפוס OrderLine.
כל אובייקט מטיפוס Customer קשור ל-0 או יותר (מספר לא מוגבל) אובייקטים מטיפוס Order.
כל אובייקט מטיפוס Order קשור לאובייקט אחד ויחיד מטיפוס Customer (לא יותר ולא פחות). בתרשים לעיל ובתרשימים הבאים המתודה getOrders()
מופיעה כמי שערכה המוחזר הוא reference למערך מטיפוס Order. נכון יותר היא להגדירה כמתודה אשר מחזירה Iterator או referece לאובייקט ה-Collection
המתאים.
כל קו אשר מתאר קשר של association
בין שתי מחלקות, יכול לכלול בכל אחד מקצותיו סימן של חץ. כיוון החץ מעיד על ה-navigability של קשר ה-association. הקו
יכול לכלול סימני חץ בכל אחד מקצותיו או רק בקצה אחד או בכלל לא. כאשר כיוון החץ
ממחלקה A
למחלקה B
המשמעות היא שבמחלקה A מוגדרת מתודה שבהפעלתה מקבלים את ה-reference
לאובייקט B הקשור. אם לאובייקט מטיפוס A יכולים להיות קשורים מספר אובייקטים מטיפוס B אז המתודה הקיימת תחזיר reference
ל-collection אשר מחזיק את כל ה-references של האובייקטים הקשורים (אובייקטים מטיפוס B).
קשר ה-association יכול להיות unidirectional association (חץ בכיוון אחד) או bidirectional
association (חצים בשני הכיוונים). לפי UML
Specification המשמעות של קו association
ללא חיצים הינה אחת מהשניים: או שקו ללא חיצים כמוהו כקו עם סימני חיצים בכל אחד
משני קצותיו או שקו ללא חיצים מתאר association
שטרם הוחלט לגביו האם יהיה bidirctional או unidirectional.
התרשים הבא זהה לתרשים הקודם. התוספת שהוא
כולל היא סימני חיצים אשר מעידים על ה-navigability של ה-association. כיווני החיצים מעידים על קיומן של המתודות הבאות:
במחלקה Order מוגדרת מתודה אשר מחזירה את ה-reference של אובייקט ה-Customer אשר קשור לאותו אובייקט Order שעליו היא הופעלה.
במחלקה Order מוגדרת מתודה אשר מחזירה reference
לאובייקטCollection אשר מחזיק את ה-references של אובייקטים מטיפוס OrdelrLine אשר קשורים לאותו אובייקט Order שעליו היא הופעלה.
במחלקה OrderLine מוגדרת מתודה אשר מחזירה את ה-reference
של אובייקט ה-Order אשר קשור לאותו אובייקט OrderLine.
לכל תיאור גראפי של
מחלקה ניתן להוסיף attributes. כל attribute
שמופיע בתיאור הגראפי של המחלקה בא לידי ביטוי באמצעות instance
variable אשר מגדירים באותה מחלקה.
ה-syntax שעל פיו מציינים בתוך תיאורה הגראפי של מחלקה את קיומו של attribute הוא:
visibility attributeName : type =
defaultValue
בתרשים הבא ניתן לראות
כי ערך ברירת המחדל של totalPrice בכל אובייקט מטיפוס Order הוא 0. כמו כן, ערך ברירת המחדל של quantity בכל אובייקט מטיפוס OederLine
הוא 1.
בתרשים UML אשר מתאר מחלקה ניתן גם לתאר את ה-operations אשר קיימים במחלקה מסוימת. ה-operations באים לידי ביטוי במתודות אשר יוגדרו במחלקה (כאשר היא תוגדר). ה-operation
וה-method הם
שני מושגים נפרדים. ה-operation הוא הקריאה לפעולה. ה-method הוא ה-implementation עצמו. כך למשל, כאשר יש מצב של פולימורפיזם, ניתן לזהות את
התרחשותו של operation
שוב ושוב כאשר מה שמתבצע בפועל, בכל קריאה כזו, היא method
אחר (בהתאם לאובייקט שעליו מופעל ה-operation). ה-syntax שעל פיו מציינים בתוך תיאורה הגראפי של מחלקה את קיומו של operation
הוא:
visibility
operationName (parameterList) : returnType {propertyStrings}
ה-visibility
יכול להיות אחד הסימנים הבאים:
+ כדי לציין
שהרשאת הגישה היא public
- כדי לציין שהרשאת הגישה
היא private
# כדי לציין שהרשאת הגישה
היא protected
אם לא שמים כל סימון בתור visibility אז המשמעות היא שהרשאת הגישה היא package
friendly.
ה- operationName
הוא שמה של המתודה.
ה-returnType הוא טיפוס הערך המוחזר על ידי אותה מתודה. בשלב התיאור הגרפי ניתן
לתאר operation
שערכו המוחזר יכול להיות ממספר טיפוסים שונים.
ניתן להוסיף את רשימת
שמות ה-properties
שהמתודה עושה בהם שימוש. זהו ה-propertyStrings.
ה-parametersList היא רשימת הפרמטרים שהמתודה יכולה לקבל בעת הפעלתה. כל פרמטר
ברשימת פרמטרים זו מופיע בפורמט הבא:
direction
name:type=defaultValue
בין כל אחד מן הפרמטרים
מופיע פסיק מפריד. ה-direction יכול לקבל את אחד משלושת הערכים הבאים:
in אם הפרמטר משמש כקלט לפעולתה של המתודה.
out אם הפרמטר משמש למטרות פלט עבור המתודה.
inout אם הפרמטר משמש גם למטרות פלט וגם למטרות קלט.
אם לא מציינים שום direction אז
ברירת המחדל הוא in.
התרשים הבא מציג את
שהוסבר באמצעות הגדרת ה-operation: setPrice
במחלקה OrderLine:
בכתיבת שמות הפרמטרים של
המתודה נהוג לוותר על ציון שמם, ערך ברירת המחדל שלהם ועל היותם in או
out או
inout.
בין מחלקות שונות
שמתוארות ב-Class Diagram
ניתן לזהות קשרים מסוגים שונים.
בין שתי מחלקות מתקיים הקשר
Generalization אם ניתן לומר על המחלקה
האחת כי היא כוללת את כל האלמנטים (operations, attributes ו-associations)
אשר קיימים במחלקה האחרת. התרשים הבא מציג את המחלקות Employee ו-Manager ואת קשר ה-Generalization שמתקיים ביניהן. באופן דומה, התרשים מציג את קשר ה-Generalization
אשר קיים בין Company ו-
HiTechCompany.
התרשים
הבא מציג קשר של Generalization בין מספר מחלקות.
כאשר רוצים לתאר operation
שהינו, למעשה, מתודה סטטית יש למתוח קו מתחת לשם של אותו operation
(כפי שזה מופיע בתרשים). התרשים הבא מדגים זאת.
לכל אובייקט יש טיפוס. בתרשים אשר מציג single
classification כל אובייקט שייך לטיפוס אחד בלבד. טיפוס
זה יכול לרשת מטיפוסים אחרים אך זהו טיפוס אחד. בתרשים אשר מציג multiple classification כל אובייקט יכול
להיות משויך ליותר מטיפוס אחד וטיפוסים אלה – אין כל חובה שיהיו קשורים בקשר של
הורשה. התרשים הבא מדגים זאת.
תרשים זה מתאר מצב שבו כל אובייקט משויך
לשלושה טיפוסים אשר מקוטלגים תחת השמות: sex, student ו-worker.
התרשים מתאר מצב שבו כל אובייקט יהיה:
מטיפוס Male או
Female
מטיפוס Student, PrivStudent או
ProffStudent
מטיפוס Employee, Manager, Teacher או
Clerck
בכל אובייקט יבוא לידי ביטוי טיפוס אחד
מכל אחת משלושת הקבוצות. כך למשל, אובייקט מטיפוס ProffStudent ו-Teacher
שאיננו מטיפוס Female או Male
איננו חוקי. כך למשל, אובייקט לא יכול להיות גם מטיפוס Teacher
וגם מטיפוס Clerck.
כל קבוצה של טיפוסים אשר מקוטלגת תחת שם
אחד (sex, student או
worker) – רק טיפוס אחד
ממנה יבוא לידי ביטוי באובייקט המוגדר. באמצעות קטלוג הטיפוסים לקבוצות מובהרים
צירופי הטיפוסים האפשריים. כל אחד משמות קבוצות הטיפוסים (sex, student ו-worker)
קרוי גם בשם Discriminator.
בתרשים אשר מתאר multiple
classification ניתן לתאר Dynamic
Classification באמצעות הוספת השורה: <<dynamic>>
ליד ה-discriminator. התרשים הבא מציג
מצב שבו אובייקט יכול לשנות את טיפוסו מקבוצת הטיפוסים הקרויה בשם worker
באופן דינמי תוך כדי ריצת התוכנית.
בין שתי מחלקות יכולים להתקיים מספר סוגים
שונים של קשרים. חלקם כבר נסקרו. בין שתי מחלקות מתקיים קשר של aggregation כאשר ניתן לומר על
מחלקה אחת שהיא part of המחלקה האחרת. כך למשל ניתן לומר על
המחלקות School ו-Teacher כי קיים ביניהן קשר של aggregation.
כל אובייקט מטיפוס Teacher יכול להשתייך לאובייקט מטיפוס School.
בין שתי מחלקות מתקיים קשר של composition אם אובייקט מטיפוס
המחלקה האחת עשוי להשתייך לאובייקט אחד ויחיד (לא יותר!) מטיפוס
המחלקה האחרת. כך למשל, ניתן לומר על המחלקות Wheel ו-Car כי
מתקיים ביניהן קשר של composition: כל מכונית מורכבת,
בין היתר, גם מגלגלים. כל גלגל משויך למכונית אחת בלבד. כמו כן, בין שתי מחלקות
שמתקיים ביניהן קשר של composition האובייקטים שנוצרו
מהן מתקיימים יחדיו (משך החיים שלהם בדרך כלל משותף). כך למשל, ניתן לומר כי כאשר
אובייקט מטיפוס Car מסיים את חייו יחד
עימו מסיימים את חייהם גם האובייקטים מטיפוס Wheel
אשר היו מחוברים אליו.
קשר של aggregation
בין מחלקה אחת לאחרת יתואר באמצעות קו שבקצהו אשר ליד המחלקה האחת יופיע מעויין
בצבע לבן. קשר של composition בין מחלקה אחת
לאחרת יתואר באמצעות קו שבצידו אשר ליד המחלקה האחת יופיע מעויין בצבע שחור.
התרשים הבא מציג קשרי composition ו-aggregation.
בין המחלקה Car
למחלקה Wheel מתקיים קשר של Composition
מכיוון שבכל מכונית יש 4 גלגלים. באופן דומה גם בכל אופניים יש שני גלגלים. כיוון
שהקשר בין Car ו-Wheel
והקשר בין Bicycle ו-Wheel הם
קשרי Composition המשמעות היא שכל
גלגל (כל אובייקט מטיפוס Wheel) יכול להשתייך
למכונית (אובייקט מטיפוס Car) או לאופניים
(אובייקט מטיפוס Bicycle) אך לא לשניהם.
בין המחלקה Driver
למחלקה Car ובאופן דומה גם
למחלקה Bicycle מתקיים קשר של Aggregation.
לכל מכונית משויך נהג אחד וכך גם לכל אופניים משויך נהג אחד. אותו נהג שמשויך
למכונית – אין כל מניעה כי ישויך גם לאופנים.
דרך רשמית נוספת לתיאור composition
בין מחלקות מוצגת בתרשים הבא:
כדי לסמן מחלקה כמחלקה כ-Abstract
Class יש לכתוב את שמה אשר מופיע בתוך המלבן שמתאר אותה באותיות נטויות
(כתב איטלקי italic) או לחילופין,
להוסיף ליד שמה את הטקסט {abstract}. שתי הדרכים
מקובלות ואפשריות. את המתודות האבסטרקטיות גם נהוג לכתוב בכתב איטלקי (italic).
התרשים הבא מציג Abstract
Class. המחלקה האבסטרקטית היא Shape
והמתודה האבסטרקטית שמוגדרת בה היא area().
כדי לתאר interface ב-Class
Diagram שמכינים יש להוסיף מעל השם (השם יכתב ב-italic)
את הטקסט: <<interface>> .
חץ אשר מתאר implementation של interface
מסוים במחלקה אשר מגדירים יופיע בקו מקוקו. התרשים הבא מתאר interface
אשר מיושם במספר מחלקות.
קיימת דרך נוספת לתיאור interfaces:
באמצעות עיגולים קטנים. דרך זו לא תוצג כאן (היא פחות שכיחה).
יש לדעת להבחין בין אובייקטים שאין להם
כפילים (אובייקטים שמייצגים את אותו דבר) – אלה ייקראו references
objects – לבין אובייקטים שכן יש להם כפילים (אובייקטים אחרים אשר מייצגים
את אותו דבר) – אלה ייקראו value
objects. value objects ייוצגו בעיקר
באמצעות ה-attributes אשר מוגדרים
במחלקה. ה-value objects יבואו לידי ביטוי
בעיקר באמצעות קשרי composition ולעיתים גם בקשריaggregation.
כך, למשל, אם במערכת יש אובייקטים רבים
אשר מייצגים תאריכים שונים (אובייקטים מטיפוס Date) –
אובייקטים אלה ייחשבו ל-value objects ובמחלקות שונות
נוכל למצוא attributes מטיפוס Date.
לעומת זאת, אובייקט מטיפוס Account אשר מייצג חשבון
בנק ייחשב ל-reference object וניתן יהיה לזהות
קשרים (כגון aggregation ו-composition)
בין המחלקה Account למחלקות אחרות,
כגון Bank ו- Customer.
בקשרים בין מחלקות, כאשר הקשר הוא כזה
שבקצהו יכול להיות יותר מאובייקט אחד, ניתן להתייחס לשאלה האם האובייקטים השונים
מאורגנים בקבוצה באופן שבו יש ביניהם סדר ואובייקטים יכולים לחזור על עצמם (ב-collection
מסוג list) או באופן שבו אין
ביניהם סדר ואובייקטים לא יכולים לחזור על עצמם (set)
או באופן אחר.... ניתן לעשות זאת באמצעות הוספת הערה בתוך סוגריים מסולסלות
בסמיכות לקצהו של אותו קו. כך למשל ניתן להוסיף {ordered} ובכך לציין
שהאלמנטים השונים מופיעים בסדר מסוים (ממוינים למשל).
על פי UML
Specification ניתן להוסיף {frozen} ליד כל attribute או
קצהו של association כדי לציין שהם לא ניתנים
לשינוי. המשמעות היא שימוש ב-final בתוך קוד המקור.
כאשר קשר שקיים בין שתי מחלקות מאופיין
בכך שלכל אובייקט מהטיפוס הראשון מחוברים אובייקט אחד או יותר מן הטיפוס השני
והקשר מאופיין בערך מסוים אשר מייחד אותו, נוכל לומר כי בין שני האובייקטים קיים qualified association.
כך למשל, בקשר שקיים בין המחלקה Bank למחלקה Account
ברור כי לכל אובייקט מטיפוס Bank מחובר אובייקט אחד או יותר (יותר בדרך
כלל) מטיפוס Account. אם אותו בנק מאפשר
לכל לקוח שלו לפתוח חשבון בנק אחד ויחיד הרי שניתן יהיה לומר כי כל אובייקט Account אשר מחובר לאובייקט מטיפוס Bank
שייך ללקוח אחד מסוים. במילים אחרות, נאמר כי לא ייתכן שלקוח של הבנק
יחזיק ביותר מ-Account אחד (בכל קשר בין Account ל-Bank יופיע Customer אחד, ואותו Customer מסוים לא יופיע שוב
בקשר אחר שיש בין ה-Bank ל-Account). במקרה כזה ניתן לומר כי מתקיים qualified
association שמתואר על ידי התרשים הבא:
קשר בין מחלקות ניתן לאפיון נוסף באמצעות attributes ו-operations
באמצעות חיבורה של מחלקה לקו אשר מתאר את אותו קשר נתון. כל ה-operations ו-attributes
אשר מוגדרים באותה מחלקה יאפיינו, למעשה, את הקשר. כך למשל, ניתן לומר כי כל קשר
בין אובייקט מטיפוס Account לאובייקט מטיפוס Bank (זהו קשר בין המחלקות Bank ו-Account)
מאופיין בתנאי האשראי שיש לאותו חשבון מסוים. במקרה כזה ניתן להוסיף לתרשים את
המחלקה Credit, אשר תחובר לקו
שבין Bank ו-Accout.
המחלקה Credit תכלול properties ו-operations
אשר יתארו, למעשה, את ה-association שנתון. בתרשים הבא,
כל אובייקט מטיפוס Credit מאפיין קשר אחד בין
אובייקט אחד מטיפוס Account לאובייקט שני
מטיפוס Bank.
value
objects יופיעו יותר במסגרת קשרי composition
בעוד ש-references objects יופיעו יותר בקשרי aggregation.
תרשים מסוג Interaction
Diagram מתאר כיצד
אובייקטים פועלים יחדיו. תרשים Interaction
Diagram מציג את האובייקטים ואת הפעולות אשר,
בעצם, קושרות ביניהם. בדרך כלל, תרשים מסוג Interaction
Diagram מתאר Use Case
מסוים באמצעות הצגת האובייקטים אשר פועלים במסגרת אותו Use
Case ובאמצעות הצגת
ההודעות אשר עוברות ביניהם.
תרשימי ה-Interaction
Diagrams נחלקים לשני סוגים:
Sequence Diagrams ו- Collaboration Diagram.
בתרשים מסוג Sequence
Interaction Diagram האובייקט מתואר
באמצעות מלבן (בתוכו יופיע שמו ושם מחלקתו) אשר ימוקם מעל קו מקווקו אנכי אשר מסמן
את ה- object's lifeline, רצף חייו של האובייקט במהלך התרחשותו של Use
Case. כל הודעה אשר
מועברת בין שני אובייקטים מתוארת באמצעות חץ שמחבר בין שני lifelines של שני אובייקטים שונים (בין שתי נקודות זמן ברצף חייהם של שני
אובייקטים שונים). כל message אשר עובר בין שני אובייקטים כולל לכל הפחות את שם ה-message
(ניתן לכלול גם ארגומנטים ואינפורמציה נוספת).
ניתן לתאר self
call, מצב שבו האובייקט
שולח message
לעצמו באמצעות חץ אשר יוצר מן ה-life line שלו וחוזר אליו.
כאשר מתרחשת קריאה להפעלת מתודה אחרת
במסגרת פעולתה של מתודה נתונה ניתן לתאר זאת באמצעות מלבן נוסף שיצויר מעל המלבן
אשר מתאר את התרחשותה של המתודה הנוכחית.
ניתן להתנות את שליחתו של message
באמצעות תנאי, condition,
אשר יופיע בתוך סוגריים מרובעות (ראה דוגמא בהמשך). כלומר, ה-message
יישלח רק אם ה-condition
הוא true.
כאשר message מסוים נשלח שוב ושוב ניתן לסמן זאת באמצעות *. סימון זה קרוי בשם iteration marker.
ניתן להוסיף מיד לאחר סימן הכוכבית סוגריים מרובעות ובתוכן הסבר נוסף בנוגע לחזרה
על שליחת ה-message
שוב ושוב.
סדר שליחת ה-messages הוא לפי סדר הופעתם מלמעלה למטה.
כאשר נשלח message ומתרחשת חזרה, יש לסמן חזרה זו באמצעות חץ מקווקו.
Asynchronous
Message יתואר באמצעות חץ שראשו
כולל רק קו אחד מבין שני הקוים הקטנים שמתארים חץ.
סימן X גדול בסופו של lifeline יבטא את סוף חייו של האובייקט שזהו ה-lifeline שלו.
התרשים הבא מציג Sequence
Interaction Diagram אשר מציגה ה-Use Case
אשר מתאר תהליך רכישה של ספרים ב-www.amazon.com.
ניתן להוסיף בצידו השמאלי של התרשים הסבר
טקסטואלי במקביל לכל אחת מהעברות ה-messages. כל אחד מהסברים אלה אשר יופיע באותה שורה של העברת message
שאותו הוא מסביר יכול להוסיף להבנת התרשים.
בתרשים מסוג Collaboration Interaction
Diagram האובייקטים מיוצגים באמצעות
מלבנים כשבתוך כל אחד מהם מופיע שמו של האובייקט ושם מחלקתו. בין השניים יופיעו
נקודותיים כשמשמאלם שם האובייקט ומימינם שם המחלקה. ניתן לוותר על אחד מהשניים אך
את הנקודותיים תמיד יש לרשום כדי שאם יופיע שם אחד יהיה ברור אם זהו שמו של
אובייקט או שמה של מחלקה. כל אחד מה-messages אשר יופיע בתרשים יופיע בצירוף מספר אשר יעיד על עיתוי שליחתו
בסדרת ה-messages.
המיספור יכול להיות באמצעות מספרים שלמים רגילים או בשיטה אחרת, כגון באמצעות
מספור דסימלי (מספר בצירוף נקודה עשרונית ואחריה מספר שלם אחר ושוב נקודה עשרונית
וכך הלאה...).
התרשים
הבא מציג Collaboration Interaction Diagram
אשר מתאר את ה-Use Case קניית ספרים באמזון.
תרשים מסוג Object
Diagram מתאר את הקשרים
שקיימים בין האובייקטים במערכת בנקודת זמן נתונה. כל אובייקט מתואר באמצעות מלבן
שבתוכו מופיעה כותרת אשר מורכבת משם האובייקט ומשמה של המחלקה שממנה הוא נוצר.
ביניהם מופיעים נקודותיים. משמאלם של הנקודותיים מופיע שמו של האובייקט ומימינם
מופיעה שם המחלקה שלו. הכותרת תופיע בצירוף קו תחתי. מתחת לכותרת מופיעים שמות
המשתנים וערכיהם. למעשה, ניתן לראות ב-Object
Diagram תרשים מסוג Collaboration Interaction Diagram
ללא messages.
התרשים הבא מציג דיאגרמה מסוג Object Diagram
אשר מתארת אובייקטים שמקיימים ביניהם קשרים בעת תהליך רכישת ספר/ים מ-AMAZON.
ניתן ליצור תרשים אשר מציג את ה-packages
שיש ואת הקשרים ביניהם. את ה-package מתארים באמצעות מלבן (שם ה-Package בתוכו) ומעליו בפינה השמאלית (צמוד אליו) מלבן קטן נוסף. המינוח package diagram
איננו מונח רשמי של UML. מבחינת UML
Specification זהו Class Diagram
אשר מציג את ה-packages ואת הקשרים ביניהם. התרשים הבא מציג תיאור
גרפי של מספר packages
ואת הקשרים ביניהם.
לחילופין, ניתן גם לצייר בתוך המלבן
שמייצג את ה-package את
ה-Class Diagram של
המחלקות אשר שייכות אליו. במקרה כזה, שם ה-package ייכתב בתוך המלבן הקטן. התרשים הבא מציג אפשרות זו.
קשר של dependency קיים בין שני packages אם שינוי באחת המחלקות שב-package מסוים עלול לגרום לכך שיהיה צורך לשנות מחלקה/מחלקות אשר שייכות
ל-package
האחר. במלים אחרות, אם ניתן לזהות שתי מחלקות בשני packages שונים שמתקיים ביניהם קשר של dependency
אז ניתן לומר כי בין שני ה-packages קיים קשר של dependency. כדאי לשים לב לכך שקשר של dependency
איננו transitive. כיוון החץ שמתאר קשר של dependency
הוא לכיוון ה-package ששינויים שיתרחשו בו עלולים לגרום לכך שיהיה צורך לבצע שינויים ב-package
שממנו החץ יצא. בתרשים האחרון ניתן לומר כי בין clerckUI לבין javax.swing קיים קשר של dependency במובן ששינויים ב-javax.swing עלולים לגרום לכך שיהיה צריך לבצע שינויים ב-clerckUI.
package
נתון יכול לכלול packages
אחרים. התרשים הבא מציג זאת.
אם קיים package שניתן לומר כי כל ה-packages האחרים מקיימים עימו קשר של dependency ניתן לציין זאת בתרשים באמצעות הוספת הטקסט: <<global>> אל אותו package מסוים. התרשים הבא מציג זאת.
בין שני packages יכול להתקיים קשר של generalization אם package אחד כולל בתוכו interfaces ו-abstract classes וה-package האחר כולל את המחלקות אשר מיישמות את אותם interfaces או יורשות מאותן abstract
classes. ה-package
אשר כולל בתוכו את ה-interfaces ו/או ה-abstract classes יסומן באמצעות {abstract}.
התרשים הבא מציג זאת.
מן התרשים ניתן ללמוד כי כשם שבעבודה עם
מחלקות ניתן לבצע polymorphism
ניתן לבצע זאת גם עם packages. בין שני packages אשר מקיימים ביניהם קשר של generalization קל וחומר כי מתקיים ביניהם גם קשר של dependency. אין צורך לציין זאת. מעצם קיומו של generalization כל פלוני יוכל להסיק גם את קיומו של dependency.
State Diagrams
State Diagrams מתארים את המצבים
השונים שבהם יכול להימצא אובייקט נתון וכיצד מצבו משתנה כתוצאה מה-events
השונים אשר מתרחשים. ביצירת state diagram יש להבחין בין actions ו-
activities.
בעוד ש-actions הן
פעולות אשר מתרחשות במהירות גבוהה יחסית מבלי שתתרחשנה הפרעות (בדרך כלל) activities הן
פעולות מתמשכות אשר במהלך ביצוען עתידות להתרחש הפרעות (events).
כאשר מתבצעת activity ניתן לומר על האובייקט כי הוא נמצא במצב, state,
מסוים. מסיבה זו ניתן לראות בתרשים מלבנים אשר מייצגים state
רגיל ומלבנים אשר מייצגים activity (מעין state).
המעבר
ממצב למצב (מ-state
ל-state)
מכונה transition.
ה-transition
מתואר באמצעות חץ כשעליו מופיעה תווית אשר מספקת אינפורמציה נוספת. תווית זו כוללת
שלושה חלקים אופציונליים (לא כולם חייבים להיות):
Event
Guard
Action
ה-Event
הוא האירוע אשר בעקבות התרחשותו ה-transition
יתבצע. אם לא צוין event
אז ה-transition
יתבצע מייד עם תום כל ה-activities
אשר משויכות לאותו state
מסוים.
ה-Action
היא הפעולה אשר תתבצע במהלך ביצועו של ה-transition.
ה-Action
יופיע בתוספת ' / ' בתחילתו.
ה-Guard
הוא התנאי הלוגי שחייב להיות true כדי שה-transition האמור אכן יתבצע.
מכל state
יכול להתבצע רק transition אחד (ל-state אחר). מסיבה זו ה-Guards אשר מוצמדים ל-transitions שונים אשר יוצאים מאותו state
יוגדרו באופן אשר יבטיח את קיומה של דרישה זו.
התרשים הבא מציג state
diagram
אשר מתאר את המצב שבו יכול להימצא אובייקט מטיפוס BooksOrder
אשר מתאר את הזמנת הספרים אשר נעשתה על ידי לקוח מסוים באתר www.amazon.com.
כפי שניתן
לראות מן התרשים, “Delivery
Creating”, “Checking”, “Waiting
for Books”
הם activities
ו-“Sent” הוא state
פשוט. כאשר במצב מסוים (state) מתרחשת activity
מסוימת אז ניתן לתאר זאת באמצעות do /
activityDescription.
אם המשתמש
מחליט במהלך ההתרחשויות לבטל את ההזמנה שהוא מבצע הרי שאז מדובר ב-state חדש, “Canceled”.
ה-transition
ל-state
זה עשוי להתרחש מכל אחד מן ה-activities:
Checking,
Delivery
Creating
ו-Waiting for
books.
ניתן לתאר זאת
באמצעות התרשים הבא:
לחילופין, ניתן
להתייחס אל כל ה-state
diagram
שנתונה כאל ישות אחת אשר – להקיפה במלבן גדול ולתת לה שם. בדרך זו ניתן יהיה למתוח
קו מהמלבן הגדול שנוצר אל המלבן הקטן אשר מתאר את מצב הטבע Cancelled.
התרשים הבא מציג אפשרות
זו.
כאשר מציינים transition
על התרשים ומציינים ב-label
שלו action
ניתן לצרף לאותו action
את התוספות הבאות:
after
(..)
כשבתוך הסוגרים יצוין משך הזמן שרק כאשר יחלוף ה-action יתבצע
when(condition)
כשבתוך הסוגריים יצוין תנאי שרק כאשר הוא יתקיים ב-action יתבצע.
ניתן
להשתמש ב-state
diagrams
כדי להציג מצב שבו יותר מ-thread
אחד פועל על האובייקט שנתון. במקרה כזה, התרשים שמתקבל נקרא Concurrent State Diagram.
תרשים מסוג זה מציג את המצבים שבהם נמצא האובייקט בכל אחד מה-threads
אשר פועלים עליו. הדוגמא הבאה מציגה אובייקט אשר מייצג קופה בבנק (אובייקט מטיפוס Cashier).
אובייקט מטיפוס Cashier
מייצג את קופת הכסף בסניף בנק אשר כל העת יש מי שמפקידים אליה כסף ומי שמושכים
ממנה כסף. התרשים מתאר את מצבה של הקופה לאורך יום עסקים אחד.
ה-Activity
Diagrams מתארים את
הפעילויות אשר מתרחשות. הסימול הגראפי העיקרי בתרשים זה הוא אליפסה אשר מייצגת activity
state מסוים. מצב activity
state הוא מצב שבו משהו נעשה:
משהו שהוא פעולה מוחשית בעולם שבו המערכת מטפלת או משהו פחות מוחשי כגון הרצה של
תכנה מסוימת. תרשים ה-Activity
Diagram כולל, בעיקר, סדרה
של activity states
ומציג את האופן שבו מתבצעים המעברים בין activity
state אחד למשנהו. ה-Activity Diagram
הבא מציג ה-activities
שמתרחשות כאשר מתבצעת הזמנה של ספרים ב-www.amazon.com.
כפי שניתן לראות, Activity
Diagram היא למעשה State Diagram
שבו כל ה-states הם
activities.
ב-Activity
Diagram ניתן לזהות את המרכיבים
הגרפיים הבאים:
כל activity
מתוארת באמצעות אליפסה.
כל branch הוא נקודת פיצול שבה הזרימה מ-activity מסוים מתפצלת
למספר כיוונים אשר מוליכים ל-activities
שונים. ב-branch
המשך זרימת הפעילות נעשה רק באחד הכיוונים האפשריים. ה-branch יתואר באמצעות מעויין. על הקווים שיוצאים ממנו ומוליכים לאחת ה-activities האפשריות יירשמו התנאים (בתוך סוגרים מרובעות) אשר יקבעו את המשך
זרימת הפעילות. ה-branch
שניתן לזהות בתרשים הוא המעוין שמתחת ל- “prepare books package”. כאשר ה-activity:
“prepare
books package” מסתיים ה-activity הבא אשר יתרחש הוא אחד ה-activities הבאים: “prepare for fast delivery” או “prepare for
regular delivery”.
כל merge הוא נקודת
חיבור של מספר כיווני זרימה לכיוון זרימה אחד והוא מתואר באמצעות מעויין (כמו branch). בתרשים ניתן לזהות את ה-merge
אשר נמצא מתחת ל-activities:
“prepare
for fast delivery” או “prepare for
regular delivery”. ה-merger
יבוא בסיומו של branch.
כאשר זרימת פעילות
מתפצלת לשני כיווני זרימה אשר יתבצעו במקביל נקודת הפיצול תתואר באמצעות מלבן שחור
אשר ייקרא בשם fork נקודת החיבור של כיווני הזרימה המקבילים חזרה לכיוון זרימה אחת
תתואר באמצעות מלבן שחור אשר ייקרא בשם join.
בתרשים ניתן לזהות את ה-fork
שמתחת ל-“receive a book order” ואת ה-join אשר נמצא מעל ל-“send the package”. הזרימה אחרי join תתרחש רק אם כל קווי
הזרימה אל ה-join
יגיעו אל סיומם. רק אז הזרימה תמשיך...
כל join
ימוקם בהתאמה ל-fork
מסוים.
ניתן לתאר conditional
thread באמצעות הוספת תנאי (בתוך
סוגריים מרובעות) ליד קו הזרימה של ה-thread
שרוצים לקבוע כ-conditional thread.
קו זרימה שנקבע כ-conditional thread
– אם התנאי הוא false
אז thread זה יפסיק לפעול אם כל ה-threads
האחרים שפועלים במקביל (ושאינם conditional)
הסתיימו והגיעו אל ה-join.
התרשים הבא מציג שלוש פעילויות מקבילות של חברת הדרכה לקראת פתיחתו של קורס: marketing (שיווק), registration
(הרשמת תלמידים עד למילוי מקומותיו של הקורס) ו-trainer
appointing (מינוי של מדריך לקורס).
פעילות ה-marketing
נקבעת כ-conditional
thread והמשמעות לכך היא שברגע
שמסיימים עם מינויו של מדריך לקורס וכמו כן גם עם רישומם של מספיק תלמידים פעילות
ה-marketing תופסק.
.
את
ה-activity הנתון ניתן לפרק למספר תת activites ולתאר זאת בתרשים פנימי בתוך המלבן אשר מתאר את ה-activity שפורק.
אם אחד ה-activitie מתבצע שוב ושוב ניתן לתת לכך ביטוי באמצעות הוספת * בתוך המלבן
שמתאר אותו. דרך פעולה זו עדיפה על פני בניית לולאה אשר מסרבלת את התרשים
כולו. התרשים הבא מציג את השימוש ב-* ואת שבירתו
של activity
למספר תת activities.
כדי שניתן יהיה להבין מה-Activity Diagram מי
מבצע (או אחראי לביצוע) של כל אחת מהפעילויות שמופיעות בתרשים ניתן להוסיף קווים
אנכיים אשר מחלקים את הפעילויות לתחומי אחריות של אובייקטים/מחלקות או גורמים
אחרים. בתרשים הבא ניתן לראות מי אחראי לכל אחת משלושת הפעילויות שמתרחשות לקראת
פתיחתו של קורס חדש.
2000 © All
the rights reserved to
Haim Michael & Zindell Publishing House Ltd.
No
parts of the contents of this paper may be reproduced or transmitted
in
any form by any means without the written permission of the publisher !
This
book can be used for personal use only !!!
Brought
to you by ZINDELL
נספח ו':
פקודות
שכיחות ב-SQL