כימוס

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש

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

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

דוגמה[עריכת קוד מקור | עריכה]

הדוגמה הבאה מדגימה איך כימוס מאפשר שינוי מימוש פנימי ללא שינוי הקוד החיצוני. הקוד הבא ב-++C מתאר מחסנית הממומשת באמצעות תור סטנדרטי:

#include <deque>
class MyStack {
private:
  std::deque<int> m_queue;
public:
  void push(int x) {
    m_queue.push_front(x);
  }
  int pop() {
    int x = m_queue.front();
    m_queue.pop_front();
    return x;
  }
};

ניתן לשנות את המימוש הפנימי לרשימה משורשרת:

#include <list>
class MyStack {
private:
  std::list<int> m_list;
public:
  void push(int a) {
    m_list.push_front(a);
  }
  int pop() {
    int a = m_list.front();
    m_list.pop_front();
    return a;
  }
};

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

#include <iostream>
int main() {
  MyStack s;
  s.push(17); s.push(11);
  std::cout << s.pop() << std::endl;
}

למרות שההתנהגות תהיה זהה בשתי הגרסאות, ייתכנו הבדלים בזמני הריצה.

דוגמאות מתחומים הנדסיים אחרים[עריכת קוד מקור | עריכה]

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

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

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

כימוס והורשה[עריכת קוד מקור | עריכה]

כאמור, מטרת הכימוס היא להסתיר פרטי מימוש מקוד חיצוני. בהקשר זה, לא תמיד ברור אם קוד מחלקה יורשת נחשב פנימי או חיצוני. מצד אחד, ייתכן שקוד המחלקה היורשת נכתב על ידי מתכנת אחר שאינו בקיא בפרטי המימוש של מחלקת הבסיס. מצד שני, המשתנים של מחלקת הבסיס מהווים חלק מהמחלקה היורשת. שפות תכנות מסוימות, מאפשרות שליטה על רמת הכימוס ביחס למחלקה יורשת. ב - Java וב - ++C לדוגמה, ניתן להגדיר אלמנטים במחלקה כ- protected וכ- private. למרות ששתי הרשאות הגישה האלה, מסתירות את המימוש הפנימי מקוד חיצוני, רק הראשונה איננה מסתירה אותו ממחלקות יורשות.

ראו גם[עריכת קוד מקור | עריכה]