» נושאי לימוד
» נושאי לימוד
יום שני 29 באפריל 2024
Callbacks - קריאה לאחור I
דף ראשי  מתקדמים   Callbacks - קריאה לאחור I גרסה להדפסה

- Callbacks  קריאה לאחור

זהו הראשון מבין שלושה שיעורים עוקבים בנושא קריאה לאחור ב-Java. שלושת השיעורים מכונים קריאה לאחור- I, קריאה לאחור- II, קריאה לאחור- III.

 

- הקדמה

- תוכנית דוגמא של השלכה כללית

              -  חלקי קוד מעניינים של השלכה כללית

              -  רישום תוכנית השלכה כללית

- תוכנית דוגמא רב השלכתית

              - חלקי קוד מעניינים של רב השלכתית

              - רישום תוכנית רב השלכתית

 


הקדמה

תהליכים רבים ב- Java API משתמשים במכניזם אשר במסגרות תכנות אחרות מתייחסים אליו כאל מכניזם של קריאה לאחור.

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

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

 

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

 

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

 

לדוגמא, נראה צורות שונות של פעילות קריאה לאחור בשילוב עם מודל האצלת האירועים בו משתמשים בממשקי משתמש גרפיים ב- JDK, במושג מבחין/ניתן להבחנה בו משתמשים בפרדיגמת מודל פיקוח על מראה, במושג תכונות כבולות ותכונות מוגבלות ב- Java Beans, וכו'. תוכל למצוא דוגמאות אלה בדפי שיעורים אלה.

 

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

 

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

 

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

 

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

 

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

 

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

 

ללא דיון נוסף, הבא נסתכל על קצת קוד.

תוכנית דוגמא של השלכה כללית

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

 

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

 

התוכנית מגדירה מחלקת מורה בעלת היכולת

        ·   ליצור ולהחזיק ברשימה של אובייקט אחד (בלבד) של סוג הממשק
    (אובייקטים מרובים הם בשלב מאוחר יותר),

        ·  לידע אובייקט זה שמשהו מעניין התרחש על ידי עוררות פונקצית ()callBack .

 

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

 

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

 

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

 

לבסוף, התוכנית מגדירה מחלקה שולטת אשר קושרת את כל החלקים יחד ומתרגלת אותם.

 

התוכנית נבדקה תוך שימוש ב-JDK 1.1.3.  תחת Win95.

פלט התוכנית מוצג במלואו ברישום התוכנית המלא בחלק מאוחר יותר.

 

חלקי קוד מעניינים של השלכה כללית

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

 

interface CallBack{
  public void callBack();
}//end interface CallBack

 

אחר כך אנו זקוקים למחלקה שהאובייקטים שלה יכולים להחזיק ברשימת אובייקטים מסוג קריאה לאחור (אובייקטים שהמחלקה שלהם מיישמת את ממשק CallBack).

 

נתייחס לתהליך של השמת אובייקט ברשימה כרישום האובייקט.

 

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

 

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

 

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

 

אחת הפונקציות המכונה register()  שמה אובייקט ברשימה.

 

הפונקציה השניה בשם calltheRoll() מעוררת את פונקצית callBack() על האובייקט ברשימה זו.

 

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

 

class TeacherCallBack obj;
//list of objects of type CallBack
  //-----------------------------------------------------//
  //Method to add objects to the list.
  void register(CallBack obj){
    this.obj = obj;  }//end register()
  //-----------------------------------------------------//
    //Method to notify all objects on the list
  void callTheRoll(){

    obj.callBack();
  }//end callTheRoll()
  //-----------------------------------------------------//
}//end class Teacher

 

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

 

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

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

 

class Student implements CallBack{  String name;
  //-----------------------------------------------------//
    Student(String name){//constructor
    this.name = name;  //save the name to identify the obj
  }//end constructor
  //-----------------------------------------------------//
   public void callBack(){
    System.out.println(name + " here");
  }//end callBack()
}//end class Student

 

לבסוף, אנו זקוקים למחלקת שליטה אשר תקשור את כל החלקים יחד, ותתרגל אותם.

פונקצית main() במחלקה זו:

        · מאתחלת אובייקט ממחלקת מורה בשם missJones ,

        · מאתחלת אובייקט תלמיד אנונימי בשם Joe ורושמת את האובייקט על הרשימה
  המוחזקת בידי
missJones

        · ומעוררת את פונקצית ()callTheRoll על missJones על מנת לגרום לאובייקטים ברשימה 
  לקבל הודעה (גורם לעוררות פונקצית ה-
callBack() שלהם).

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

 

class Callback01{
  public static void main(String[] args){
    //Instantiate Teacher object
   Teacher missJones = new Teacher();
    //Instantiate and register a Student object with the
    // Teacher object
    missJones.register(new Student("Joe"));
    //Cause the Teacher object to do a callBack on the
    // Student object.
    missJones.callTheRoll();
  }//end main()
}//end class Callback01

 

זהו זה. זוהי תוכנית פשוטה המכילה סכום ותוכן של גישה אחת לקריאות חזרה ב- Java.

 

קריטי לציין - שכל האובייקטים הרשומים ברשימה הם מסוג ממשק CallBack.

הדבר מחייב שלא יהיה אובייקט ברשימה שאין לא פונקצית אובייקט בשם callBack().

 

 02-12-03 / 22:01  עודכן ,  13-10-03 / 19:25  נוצר ע"י רונית רייכמן  בתאריך 
 סקירה - הקודםהבא - רישום תוכנית השלכה כללית 
תגובות הקוראים    תגובות  -  0
דרכונט
מהי מערכת הדרכונט?
אינך מחובר, להתחברות:
דוא"ל
ססמא
נושאי לימוד
חיפוש  |  לא פועל
משלנו  |  לא פועל
גולשים מקוונים: 3