אבסטרקציה (מדעי המחשב)

במדעי המחשב, אבסטרקציה (מאנגלית Abstraction  ובעברית: הפשטה) היא תהליך שבאמצעותו נתונים והוראות מוגדרים על ידי הצגה דומה למשמעות הסמנטית שלהם, תוך הסתרת פרטי המימוש שלהם.

מטרת האבסטרקציה להציג רק את הפרטים הרלוונטיים לנקודת המבט הנוכחית, על ידי הקטנת כמות הפרטים ו"הוצאה החוצה" של הטיפול בהם, כך שהמתכנת יוכל להתמקד רק בכמות מוגבלת של רעיונות בפרק זמן נתון.

יש לבצע אבחנה בין אבסטרקציה לבין מודולריות, בעוד מודולריות אחראית על פירוק לגורמים של הפתרון, אבסטרקציה אחראית על חיבור נתונים של הנושא עצמו לעניין מסוים. לדוגמה, כשבבית משפט לפני מתן עדות, משביעים את העד לומר את האמת, רק את האמת ואת כל האמת, המשפט ׳את כל האמת׳ מחביא בתוכו הגנה מפני אבסטרקציה. אנו משביעים את העד לספר הכול, ללא ביצוע חיבור של נתונים לעניין מסוים בלבד.

מערכת יכולה להיות מורכבת מכמה שכבות אבסטרקציה, שכל אחת מהן חושפת את המתכנת למשמעויות וכמויות שונות של פרטים. לדוגמה, שכבות אבסטרקציה נמוכות (low-level) חושפות את פרטי החומרה של המחשב, עליה רצה התוכנה, בעוד ששכבות גבוהות (high-level) מטפלות בלוגיקה העסקית של התוכנה.

רעיון האבסטרקציה במדעי המחשב החל כאנלוגיה לאבסטרקציה במתמטיקה, שם טכניקת האבסטרקציה מסתמכת על הגדרות מתמטיות, מה שהופך אותה לגישה טכנית יותר לעומת הרעיון הכללי של אבסטרקציה בפילוסופיה. לדוגמה, בשפות תכנות, מספר הוא אותו רעיון (concept) כפי שהוא מוגדר במתמטיקה. פרטי המימוש יכולים להשתנות בהתאם לסוג החומרה והתוכנה, אבל זה לא מהווה מגבלה מכיוון שרעיון המספרים במחשבים תמיד מתבסס על אותו רעיון מתמטי.

בתכנות, אבסטרקציה יכולה להיות מיושמת לשליטה (control) או לנתונים (data): אבסטרקציית שליטה היא אבסטרקציה של הפעולות ואילו אבסטרקציית נתונים עוסקת בהפשטה של מבני נתונים (ראו: מבנה נתונים מופשט).
 אבסטרקציית שליטה עושה שימוש בשגרות ורעיונות דומים לצורך בקרת זרימה.
 אבסטרקציית נתונים מאפשרת להעניק משמעות ליחידות נתונים בסיסיות (ביטים). לדוגמה, זהו המניע הבסיסי מאחורי השימוש בטיפוסי נתונים.

ניתן לראות באובייקטים (בתכנות מונחה-עצמים) כניסיון לשלב בין אבסטרקציית שליטה ואבסטרקציית נתונים.

אותה הגדרה אבסטרקטית יכולה לשמש כממשק משותף עבור משפחה של אובייקטים אשר חולקים את אותה משמעות, אבל ממומשים בדרכים שונות וכוללים התנהגות שונה. מנגנון הירושה בתכנות מונחה-עצמים יכול לשמש לצורך הגדרת מחלקה אבסטרקטית המגדירה את הממשק המשותף.

ההמלצה שמתכנתים ירבו להשתמש באבסטרקציות כאשר ניתן לעשות זאת על מנת למנוע כפילויות בקוד המקור ידועה כ"עיקרון האבסטרקציה" (abstraction principle). הדרישה ששפת תכנות תספק את האבסטרקציות הנדרשות גם היא נקראת באותו שם.

אבסטרקציית שליטה 

אבסטרקציית שליטה (control abstraction) היא אחד השירותים המרכזיים שמספקות שפות תכנות. מחשבים מסוגלים להבין רק פעולות ברמה הנמוכה ביותר, כדוגמת העברת מספר ביטים ממקום אחד בזיכרון למקום אחר ולהפיק את הסכום של שני רצפים של ביטים. שפות תכנות מאפשרות לבצע פעולות כאלה ברמה גבוהה יותר. בתור דוגמה, נסתכל על הביטוי הבא הכתוב בתחביר דמוי-פסקל (שפת תכנות עילית):

a := (1 + 2) * 5

לבן אדם זה נראה כחישוב מובן ופשוט למדי ("אחד ועוד שתיים שווה שלוש, כפול חמש שווה חמש עשרה"). לעומת זאת, השלבים ברמה הנמוכה (low-level) אשר נדרשים כדי לבצע את החישוב הנ"ל, להחזיר את הערך "15" ולבצע השמה של ערך זה למשתנה "a", הם למעשה די עדינים ומורכבים. יש להמיר את הערכים לייצוג בינארי (בדרך כלל משימה הרבה יותר מורכבת ממה שאנשים עשויים לשער) ולפרק את החישובים (על ידי מהדר או מפרש) להוראות בשפת סף (שוב, פעולות הרבה פחות אינטואיטיביות עבור המתכנת: פעולות כגון הזזה שמאלה של אוגר בינארי, או הוספה של המשלים הבינארי של אוגר אחד לתוכן של אוגר שני, הן פשוט לא הצורה שבה בני אדם חושבים על הפעולות האריתמטיות האבסטרקטיות של חיבור או כפל). ולבסוף, פעולת ההשמה של הערך המתקבל, "15", למשתנה המסומל בתווית "a", כך שמאוחר יותר ניתן יהיה להשתמש ב-"a", כוללת שלבים נוספים "מאחורי הקלעים", של מציאת התווית של המשתנה ושל תוצאת החישוב בזיכרון הפיזי או הוירטואלי, אחסון של הייצוג הבינארי של "15" באותו מקום בזיכרון, וכו'.

ללא אבסטרקציית שליטה, בכל פעם שמתכנת ירצה לבצע פעולה פשוטה כמו חיבור או כפל של שני מספרים ולשמור את התוצאה במשתנה, הוא ייאלץ לפרט ידנית את כל השלבים ברמה הבינארית של האוגרים. לעבודה כפולה כזאת יש שתי השלכות שליליות משמעותיות:
 זה מאלץ את המתכנת לחזור שוב ושוב על אותן משימות בכל פעם שיש לבצע משימה דומה.
 זה מאלץ את המתכנת לתכנת עבור חומרה וסט פקודות ספציפיים.

תכנות מובנה 
תכנות מובנה (structured programming) עוסק בפירוק משימות תוכנה מורכבות ליחידות קטנות יותר הכוללות ממשקים ברורים לבקרת זרימה בין הרכיבים, מה שמביא להורדת רמת המורכבות והפוטנציאל לשגיאות.

בתוכנית פשוטה, המטרה היא להבטיח שללולאות יהיו נקודות יציאה ברורות, וכאשר ניתן, שתהיה נקודת יציאה יחידה מתוך פונקציות ופרוצדורות. במערכות מורכבות יותר, המטרה היא לפרק משימות מורכבות להרבה מודולים נפרדים. שיטת עבודה כזאת מאפשרת לבודד את פרטי המימוש של רכיב מסוים ומגוון המתודות הפנימיות שלו מיתר הרכיבים. תכנות מונחה-עצמים מאמץ ומרחיב רעיון זה.

אבסטרקציית נתונים 

אבסטרקציית נתונים (data abstraction) כופה הפרדה ברורה בין תכונות אבסטרקטיות של טיפוסי נתונים לפרטים הקונקרטיים (concrete) אודות המימוש שלהם. התכונות האבסטרקטיות הן אלה שניתן לראותן בקוד הלקוח אשר עושה שימוש בטיפוס הנתונים - הממשק לאותו טיפוס נתונים. לעומת זאת, המימוש הקונקרטי נשמר פרטי לגמרי (מוסתר מהמשתמש), והוא אף יכול להשתנות, לדוגמה כדי להכניס שיפורי יעילות שנעשים עם הזמן. הרעיון הוא ששינויים כאלה לא אמורים להשפיע על קוד הלקוח, מאחר שהם לא כוללים שום שינוי להתנהגות האבסטרקטית (הממשק).

לדוגמה, ניתן להגדיר מבנה נתונים מופשט בשם "טבלת חיפוש", אשר משייך באופן ייחודי ערכים (values) למפתחות (keys), ומאפשר לאחזר ערך על ידי ציון המפתח המתאים לו. ניתן לממש טבלת חיפוש כזאת בדרכים שונות: כטבלת גיבוב, עץ חיפוש בינארי, או אפילו כרשימה ליניארית פשוטה של זוגות מסוג [מפתח:ערך]. מנקודת המבט של קוד הלקוח שיעשה שימוש במבנה הנתונים, התכונות האבסטרקטיות של טיפוס הנתונים הן זהות בכל אחד מהמימושים.

כמובן שעל מנת שכל זה יעבוד, יש לדאוג לנכונות פרטי הממשק מלכתחילה, מאחר שלכל שינוי מאוחר יותר עשויה להיות השפעה גדולה על קוד הלקוח. אחת הדרכים להסתכל על כך היא שהממשק מהווה חוזה בין טיפוס הנתונים לבין קוד הלקוח לגבי ההתנהגות המוסכמת; כל מה שאינו מוגדר בחוזה עלול להשתנות מאוחר יותר ללא הודעה מוקדמת.

אבסטרקציה בתכנות מונחה-עצמים 

בתכנות מונחה-עצמים, אבסטרקציה מאפשרת הגדרת אובייקטים (עצמים) המהווים "שחקנים" אשר יכולים לבצע עבודה, לדווח אודות המצב שלהם ולשנות אותו, ו"לתקשר" עם אובייקטים אחרים במערכת. בבסיס האבסטרקציה בתכנות מונחה-עצמים עומד מושג ה"כימוס" אשר מתייחס להסתרת פרטי המצב (לדוגמה, הערך של משתני המחלקה) של האובייקט, ולהרחבת רעיון טיפוס הנתונים כפי שהיה בשימוש בשפות תכנות מוקדמות יותר, על מנת לקשור חזק גם התנהגות (פונקציות) לנתונים.

כאשר מכניסים אבסטרקציה גם להגדרת הפעולות, כך שניתן להחליף בין אובייקטים מטיפוסים שונים, זה נקרא פולימורפיזם. כאשר אבסטרקציה משמשת בכיוון ההפוך, בתוך טיפוסים או מחלקות, על מנת ליצור מבנה המפשט מערכות יחסים מורכבות, זה נקרא האצלה (delegation) או ירושה (inheritance).

שפות התכנות ++C ו-Java אף מכילות מילים שמורות (keywords) ייעודיות להצהרה על אבסטרקציה: משמעות ההצהרות virtual (ב-++C) ו-abstract (ב-Java) היא שזוהי אחריות המתכנת לממש את המתודות במחלקה שיורשת מהמחלקה האבסטרקטית.

שכבות אבסטרקציה 
כסדרה של שכבות אבסטרקציה (מלמטה למעלה): חומרה, קושחה, אסמבלר, ליבה, מערכת הפעלה ויישומים
במדעי המחשב נפוץ השימוש בשכבות או רמות של אבסטרקציה, שם כל רמה מייצגת מודל שונה של אותו המידע ותהליכים, אבל משתמשת במערכת ביטויים, אובייקטים והרכבים ייחודיים אשר תקפים רק לתחום (domain) מסוים. כל רמה אבסטרקטית ו"גבוהה" יותר יחסית, נבנית על גבי רמה יחסית "נמוכה" ו"ממשית" (concrete) יותר, אשר נוטה לספק ייצוג פרטני ("גרנולרי") יותר ויותר.

לדוגמה, שערים לוגיים נבנים על גבי מעגלים אלקטרוניים; ייצוג בינארי נבנה על גבי שערים לוגיים; שפת מכונה נבנית על גבי ייצוג בינארי; שפות תכנות על גבי שפת מכונה; מערכות הפעלה ויישומים על גבי שפות תכנות. כל רמה מגולמת בשכבה שתחתיה, אבל לא נקבעת על ידה, מה שהופך אותה במידה מסוימת לשפת תיאור העומדת בפני עצמה.

ארכיטקטורה רב-שכבתית 

היכולת ליצור עיצוב המסתמך על שכבות שונות של אבסטרקציה מאפשרת:
 לפשט את העיצוב באופן משמעותי.
 לאפשר ל"שחקנים" (role players) שונים לפעול בצורה יעילה ברמות שונות של אבסטרקציה.

ארכיטקטורה רב-שכבתית מחלקת את הטיפול במשימות השונות של היישום לחלקים נפרדים (שכבות). זוהי טכניקה בעיצוב תוכנה, חומרה ותקשורת נתונים, בה רכיבי המערכת או הרשת מופרדים לשכבות כך שניתן יהיה לבצע שינויים באחת מהשכבות מבלי להשפיע על יתר השכבות.

ראו גם 
 שפת תכנות עילית
 שפת תכנות Low-level
 חוזה (תכנות)

לקריאה נוספת 
 
 
 Abstraction/information hiding - CS211 course, Cornell University.

קישורים חיצוניים 
 SimArch example of layered architecture for distributed simulation systems.

מדעי המחשב
תכנות