תכנות מונחה-עצמים
תכנות מונחה-עצמים או לעתים תכנות מוכוון-עצמים (באנגלית: Object-Oriented Programming, או בקיצור OOP) היא פרדיגמת תכנות המשתמשת ב"עצמים" (אובייקטים) לשם תכנון תוכניות מחשב ויישומים. הפרדיגמה מספקת למתכנת מספר כלי הפשטה וטכניקות ובהן הורשה, מודולריות, פולימורפיזם וכימוס.
טכניקות אלו שימשו בפיתוח תוכנה החל מתחילת שנות ה-80 ואילך, אך השימוש בפרדיגמה בשלמותה החל רק בשנות ה-90. רוב שפות התכנות המודרניות תומכות בתכנות מונחה-עצמים.
תכנות מונחה-עצמים היווה מהפכה בכתיבת תוכנה, ודרש מהמתכנתים התייחסות אחרת לפתרון בעיות ורכישת הרגלי תכנות חדשים. תכנות מונחה-עצמים הוא חלק מתפיסת פיתוח מונחית-עצמים, הכוללת גם ניתוח מערכות מונחה-עצמים (OOA), עיצוב מונחה-עצמים (OOD) ובמידה חלקית גם בסיסי נתונים מונחי-עצמים (Object-Oriented Databases).
תוכן עניינים |
[עריכה] רקע
הפרדיגמה של תכנות מונחה-עצמים צמחה מהתכנות הפרוצדורלי והמודולרי שבוסס על שגרות ופונקציות שפעלו על מבני נתונים חופשיים. שיטה זו יצרה קושי רב, מכיוון שכל שינוי בהגדרת משתנים בתוכנית חייב שינוי בפונקציות שפעלו בכל מרחב התוכנה. ככל שהתוכנה הייתה גדולה ומורכבת הקושי הלך והתעצם, דבר שגרר תחזוקה רבה ואיטיות ומורכבות בפיתוח ככל שהתקדם, וכך, בניגוד למחירי החומרה שכל הזמן ירדו, מחירי התוכנות דווקא האמירו. לפיכך היה צורך לחפש מתודולוגיה חדשה שתפשט ותקל על עבודת התכנות.
אחד מהכיוונים לטיפול בבעיה היה ביסוס של פיתוח התוכנה על מודולות, כעין "קופסאות שחורות" שניתן להשתמש בהן שימוש משותף ולהעתיקן ליישומים נוספים, בבחינת שימוש חוזר (Reuse) של קוד, ובכך לקצר את תהליך פיתוח התוכנה (דבר שיושם למשל בקובצי DLL). בהסבר פשטני מאוד, תכנות מונחה-עצמים הוא תכנות שמבוסס על יצירת "קופסאות שחורות", שיש להם חיים עצמאיים משל עצמם, ואינם תלויים בגורם חיצוני. מהתפיסה הזו התפתחה מתודולוגיה שמחקה את העולם הממשי שקיימים בו עצמים ותתי-עצמים, שלהם יש תכונות ופעולות משל עצמן. כך, כל תוכנה היא בעצם אוסף היררכי של אובייקטים רבים, שמתקשרים אחד עם השני לכדי מערכת גדולה ומתואמת.
יתרונה של מתודולוגיה זו היא שליטה בנפחים גדולים של קוד, על ידי חלוקה של עצמים לפי קטגוריות, דבר העוזר למיון וסידור המידע הרב, ועל ידי שיוך פעולות ומאפיינים לאובייקטים, כאשר מאפיינים בעלי משמעות לוגית דומה יכולים לפעול בצורה אחרת בהתאם לאובייקט שאליו הם מתייחסים. לדוגמה, התפיסה האנושית מחלקת את העולם לקטגוריות של דומם, צומח, חי ואדם, וכל קטגוריה ראשית מתחלקת שוב לקטגוריות משנה, למשפחות ותתי משפחות. התכונות והפעולות, אף שיש להם משמעות דומה, יכולים לפעול בצורה אחרת בקטגוריות השונות. פעולת הנשימה, למשל, נעשית אחרת אצל דג ואצל אריה, אף שהינה דומה מבחינה לוגית: אצל הדג הפעולה מתבצעת על ידי קליטת חמצן מהמים באמצעות זימים, ואצל האריה על ידי קליטת החמצן מהאוויר באמצעות הריאות.
[עריכה] היסטוריה
הרעיון של עצמים ומופעים שלהם הופיע לראשונה בשנת 1963 בתוכנה בשם Sketchpad.
כמתודולוגיה לפיתוח תוכנה, מומש תכנות מונחה-עצמים לראשונה בשפת הסימולציה Simula 67, שנוצרה בשנות השישים על ידי הנורבגים אולה-יוהאן דאל וקריסטן ניגארד. בשנת 2001 הוענק לשניים פרס טיורינג, בזכות תרומתם לפיתוחו של תכנות מונחה-עצמים.
פיתוח ושכלול של הרעיון נעשו בשפת Smalltalk, שפותחה בשנות השבעים בזירוקס פארק. שפה זו זכתה להכרה נרחבת ולעניין רב באקדמיה ובתעשייה, והייתה השפה הראשונה שניתן לכנותה "מונחית-עצמים".
בפיתוח תוכנה עסקית זכתה מתודולוגיה זו לתפוצה רחבה החל מסוף שנות ה־80, תחילה ב-Smalltalk ולאחר מכן בשפות התכנות C++ וטורבו פסקל, ולאחריהן בשפה Java. שפות נוספות התומכות בתכנות מונחה-עצמים הן פייתון, Ada (בגרסת 95), Ruby ,Delphi ועוד רבות אחרות.
במסגרת יוזמת NET. של חברת מיקרוסופט פיתחה החברה שפה חדשה לתכנות מונחה-עצמים, #C, והשלימה יכולת זו שהייתה חלקית בגרסה ששית של שפת Visual Basic, בגרסה הקרויה Visual Basic .NET.
[עריכה] מאפייני תכנות מונחה-עצמים
מרכיב בסיסי בתכנות מונחה-עצמים הוא המחלקה (Class). מחלקה היא מבנה מופשט בעל תכונות (Properties) המגדירות ומאפיינות את המחלקה כלפי חוץ, ופעולות (Methods), שהן פונקציות ייחודיות למחלקה. בחלק משפות התכנות קיימים גם אירועים (Events), שהם שגרות השייכות למחלקה ומוזנקות בהקשרים שונים, למשל בתחילתו או בסיומו של הליך או כתגובה לקלט מהמשתמש.
על מנת להשתמש במחלקה, המתכנת יוצר מופעים שלה. כל מופע של מחלקה הוא עצם (Object או Instance). היחס בין המחלקה לבין המופע, הוא היחס בין הגדרה של סוג טיפוס (Type) לבין הכרזה ויצירת משתנה מסוג זה. כלומר, בעוד שהמחלקה מהווה תבנית ומגדירה את התכונות והפעולות השייכות לה, העצמים הם אלה שמכילים את המידע הזה בפועל - כל עצם מכיל את התכונות והפעולות שהוגדרו במחלקה ממנה נוצר. לדוגמה, למחלקה הקרויה "מכונית" יש תכונות: צבע, דגם, שנת יצור, ופעולות: התנעה, נסיעה, עצירה. כל מכונית מסוימת היא עצם במחלקה זו, ולכל תכונה ערך המתאים למכונית המסוימת, למשל מזדה לבנה מודל 2003.
בכל מחלקה קיימות שתי פונקציות שמופעלות באופן אוטומטי על המופעים שלה בעת הופעתם ובעת מחיקתם. בעת יצירת המופע תופעל פונקציית בנאי (Constructor), באמצעותה אפשר לאתחל את האובייקט, לעתים באמצעות פרמטרים המועברים אליה. בעת הריסת האובייקט תופעל פונקציה הורסת (Destructor), באמצעותה אפשר למשל לשחרר זיכרון שהיה בשימוש על ידי העצם, או להרוס אובייקטים אחרים שכבר אין בהם צורך. בשפות המשתמשות במנגנון איסוף זבל, כגון Java, ישנה פונקציה מקבילה אך היא נקראת רק בעת ההריסה הסופית של העצם על ידי המנגנון, ולכן תפקידיה שונים.
התכנות במתודולוגיה זו מצריך תכנון ומאמץ יתר מבשיטה הרגילה, מפני שצריך לנתח ולהגדיר את המערכת כולה מראש ולבנות את כל המודל שלה, שבו יוגדרו כל האובייקטים השונים וההיררכיה שביניהם. מצד שני למתכנת המשתמש באובייקטים, הרבה יותר קל להתמצא, לפתח ולתחזק כאשר הוא מתבסס על קוד של תכנות מונחה-עצמים, מאשר על קוד פרוצדורלי.
[עריכה] עקרונות תכנות מונחה-עצמים
לתכנות מונחה-עצמים שלשה מאפיינים עיקריים: כימוס, הורשה ורב-צורתיות.
[עריכה] כימוס (Encapsulation)
|
|
ערך מורחב – כימוס |
יצירת האובייקט כמודול סגור וכ"קופסה שחורה", בה כל המכניזם הפנימי עלום וכמוס מפני המשתמש. התקשורת עם העצם מתבצעת רק דרך הפעולות והמאפיינים הכלליים הנכללים בממשק התכנות שלו, דבר המאפשר בקרה טובה על כל הפעילות עם האובייקט. כל הנתונים הפנימיים כמו גם פעולות פנימיות, המשמשים את העצם, אינם ידועים מחוץ לעצם (כלומר למתכנת המשתמש בו) ולכן מפתח האובייקט יכול לשנותם בחופשיות מבלי שיהיה צורך לשנות את התוכנות אשר משתמשות באובייקט. הדבר גם מאפשר להחליף בקלות ופשטות מנועי תכנות אשר פועלים מבחינה פנימית באופן שונה לגמרי, כל זמן שהם נותנים כלפי חוץ את אותם שיטות ומאפיינים. קשר מסוג זה בין עצמים קרוי צימוד רפוי (loose coupling), והוא מבטיח יצירת תוכנית מודולרית, פשוטה להבנה וניווט, וקלה לתחזוקה.
[עריכה] הורשה (Inheritance)
ניתן להגדיר מחלקה חדשה על בסיס מחלקה קיימת. למחלקה החדשה ישנן כל התכונות והפעולות שירשה מהמחלקה שעל-פיה הוגדרה, ובנוסף ניתן להגדיר פעולות נוספות במחלקה החדשה, או לשנות פעולות שירשה. המחלקה המורישה קרויה מחלקת בסיס (base class), מחלקת אב (parent) או מחלקת-על (superclass). המחלקה היורשת קרויה מחלקה נגזרת (derived class), בן (child) או תת-מחלקה (subclass).
דוגמה: על בסיס המחלקה "רכב" שהוא רכב שנע על גלגלים בעזרת מנוע, אפשר להגדיר את המחלקות "אופנוע", "משאית", ו"מכונית", כאשר בכל אחת מהן יהיה שינוי בצורת הרכב, במנוע ובגלגלים. על בסיס המחלקה "מכונית" ניתן להגדיר מחלקה חדשה "מונית", ובה תכונות ופעולות נוספות: כמו "כובע" המונית, הפעלת והפסקת מונה.
הדוגמה המובהקת ביותר לרעיון ההורשה מופיעה במיון עולם הטבע. בשיטת המיון ההיררכי הנהוגה בתחום זה, מוגדרות מחלקות ברמות אחדות. בכל אחת מהרמות נקבעות תכונות מסוימות, וכל רמה יורשת את התכונות של הרמות שמעליה. כאשר אנו פוגשים עצם מסוים בעולם החי, למשל כלבה ששמה "לאסי", אנו לומדים על תכונותיו על-פי המחלקה שאליה הוא משתייך.
ישנן שפות שבהן ניתן לרשת בו זמנית מכמה מחלקות בסיס, וליצור מחלקה שממזגת את התכונות של כמה מחלקות; ירושה כזאת עלולה ליצור בעיות במקרה של "ירושת יהלום", כלומר מקרה בו שתיים ממחלקות הבסיס יורשות מאותה מחלקה. בשל כך חלק מהשפות מגבילות את המנגנון לירושה ממחלקת בסיס אחת, ומימוש מספר ממשקים, שהם מחלקות נטולות מימוש.
[עריכה] רב-צורתיות (Polymorphism)
|
|
ערך מורחב – פולימורפיזם |
היכולת לתת משמעויות שונות לפעולה בהקשרים שונים, וכך להתייחס לקבוצה של עצמים שונים באופן אחיד. המשמעות של פעולה נקבעת בהקשר של כל אחת מהמחלקות שבהן מוגדרת פעולה זו, ובהתאם לעצם שבו עוסקת הפעולה. רב-צורתיות עשויה להתממש בצורה דינמית בזמן העיבוד (תכונה הקרויה late binding) או בצורה סטטית בזמן ההידור.
החשיבות הגדולה של מנגנון הפולימורפיזם היא האפשרות להפשטה (Abstraction) בתוכנה. המנגנון מאפשר כתיבת קוד כללי, מופשט, קוד הכתוב במונחי טיפוסים מופשטים ופועל כל פעם בהתאם לטיפוס הספציפי עליו הוא עובד.
מושגים הרווחים ברב צורתיות, הם:
- העמסת פרמטרים, שבו ניתן ליצור כמה פונקציות בעלות שם זהה אך בעלות פרמטרים שונים. דבר זה שימושי לריכוז כל הפונקציות תחת אותה קורת גג, במקום לכתוב פונקציות רבות בעלות שם שונה שמבצעות למעשה את אותה פעולה מבחינה לוגית.
- העמסת אופרטורים, שבו אופרטור מסוים שומר על צורתו הלוגית אך מקבל מכניזם פנימי שונה בתוך אובייקט. למשל אופרטור + שנועד לחבר מספרים, במחלקה של מחרוזות מקבל יכולת שרשור, ובמחלקה של מערכים יכול לקבל יכולת לחבר בין שני מערכים.
- דריסה (Override) שבה ניתן להחליף פונקציה של מחלקת בסיס בפונקציה שונה במחלקה הנגזרת ממנה. טכניקה נוספת היא הצללה שדומה ליכולת הדריסה.
דוגמה: אם נצמד לדוגמה הקודמת של כלי רכב, כאשר יורשים את מחלקת רכב, למשאית ולמכונית בשתיהן מדובר על מנוע, אבל המנוע יהיה אחר ואף שפעולותיו יהיו בשמות דומים הוא עשוי לבצע פעולות אחרות.
דוגמה נוספת: פעולת החיבור מוגדרת במחלקת המספרים הטבעיים, במחלקת המספרים הממשיים, במחלקת המספרים המרוכבים וכו'. בכל המחלקות הפעולה קרויה "חיבור", וניתן להשתמש בה באופן אחיד בקבוצת מספרים, בלי תלות במחלקה אליה משתייכים מספרים אלה.
[עריכה] ראו גם
[עריכה] קישורים חיצוניים
- קורס תכנות מונחה-עצמים בשפת Java שניתן באוניברסיטת תל אביב
- קורס תכנות מונחה-עצמים בשפת C++ שניתן באוניברסיטת תל אביב (מניח ידע בשפת C)
- פרויקט תכנות מונחה-עצמים – אינדקס, באתר בנית אתרים