» נושאי לימוד
» נושאי לימוד
יום שני 29 באפריל 2024
קטעי קוד מעניינים
דף ראשי  מתחילים  תֶכֶן מונחה-עצמים - בעיית בד הציור  קטעי קוד מעניינים גרסה להדפסה

 

קטעי קוד מעניינים

 

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

 

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

 

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

 

המחלקה מסוגלת לבקש מן המשתמש לקבוע את גודל הציור שלו, ולהעביר את המידע הזה לאובייקט של Canvas ולאובייקט של WoodenFrame באמצעות הודעות מתאימות שהיא שולחת להם.

 

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

 

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

 

public class Ood03{//controlling class
  private Canvas canvas = new Canvas();
  private WoodenFrame woodenFrame = new WoodenFrame();

 

 

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

 

לאחר מכן הקוד ב‑()main מפעיל מתודות קלט ופלט על האובייקט, תחילה כדי לקבל מהמשתמש את גודל הציור ואת יחידת העלות, ואחר כך כדי לדווח למשתמש על הגודל הכולל והעלות הכוללת.

 

  public static void main(String[] args){
    Ood03 painting = new Ood03();
    painting.getInput();
    painting.showOutput();
  }//end main

 

 

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

 

ההוראה הראשונה במתודה יוצרת אובייקט  utility  מטיפוס EasyIn על מנת להקל על הטיפול בקלט המגיע מהמקלדת. מחלקת EasyIn איננה ייחודית לתֶכֶן הזה. כדאי לראות בה ספריית מחלקה מקומית.

 

(עם זאת, תוכל למצוא תוכנית לדוגמה מעניינת שממחישה כיצד להשתמש במחלקות reader/writer של זרימת תווים, שהוכנסו לשימוש ב‑1.1 JDK.)

 

לאחר מכן מוצהר משתנה זמני מטיפוס double שנועד למיגוון של שימושים.

 

  private void getInput(){
    EasyIn easy = new EasyIn();
    double temp;//temporary double variable

 

 

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

 

תחילה המתודה שולחת הנחיה למשתמש ומבקשת ממנו להקליד את אורך הציור באינטשים. האורך נקרא מן המקלדת כ‑double .

 

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

 

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

 

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

 

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

 

ניתן היה גם לכלול את האטריבוטים המשותפים length ו‑width במחלקת-על ולהרחיב אותה כדי ליצור מחלקות בשם Canvas ו‑WoodenFrame. אולם, לדעתי, אפשרות כזו לא הייתה מועילה בשלב זה לתֶכֶן.

 

    System.out.println(
      "Enter length of painting in inches");
    temp = easy.readDouble();
    canvas.setLength(temp);
    woodenFrame.setLength(temp);

 

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

 

בזאת תם הדיון במתודת getInput() .

 

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

 

המידע שהתקבל מהאובייקטים של Canvas ושל WoodenFrame מוצג למען המשתמש באמצעות מתודת showOutput() .

 

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

המתודה מציגה מידע זה למען המשתמש.

 

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

 

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

 

  private void showOutput(){
    System.out.println("Length of wood to buy is: " 
         + woodenFrame.getTotalLengthToBuy() + " inches");

 

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

 

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

 

getTotalMaterialCost() שולחת הודעות לאובייקטים של WoodenFrame ושל Canvas ומבקשת מכל אחד מהם לדווח על העלות שלו. המתודה מסכמת את שתי העלויות הללו ומחזירה את סכום העלויות בתור העלות הכוללת של הפרויקט.

 

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

 

    System.out.println("Total cost: " 
               + this.getTotalMaterialCost() + " dollars");

 

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

 

  private double getTotalMaterialCost(){
    return (canvas.getTotalCost() 
                            + woodenFrame.getTotalCost());
  }//end getTotalMaterialCost()

 

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

 

כעת נדון במחלקת Canvas .

 

מחלקת Canvas מייצגת החומר המשמש לכיסוי המסגרת של הציור.
יש בה את משתני המופע הבאים:

 

·       length

·       width

·       costPerSqFt

 

הערכים length ו‑width מייצגים את אורך ורוחב הציור ומשמשים לחישוב האורך והרוחב הדרושים עבור הבד.

 

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

 

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

 

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

 

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

 

·       אורך כולל

·       רוחב כולל

·       עלות כוללת

 

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

 

class Canvas{
  private final double margin = 5.0;
  private double length; //length of the painting
  private double width; //width of the painting
  private double costPerSqFt; //cost of the canvas  

 

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

 

  public void setLength(double length){
    this.length = length;
  }//end setLength()
  //-----------------------------------------------------//
  
  public void setWidth(double width){
    this.width = width;
  }//end setWidth()
  //-----------------------------------------------------//
  
  public void setCostPerSqFt(double costPerSqFt){
    this.costPerSqFt = costPerSqFt;
  }//end setCostPerSqFt()

 

 

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

 

במקרה זה האורך הכולל הוא סכום של אורך הציור ואורך השוליים הדרושים לשם מתיחת הבד סביב המסגרת. גם הרוחב הכולל מחושב בדרך דומה.

 

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

 

  public double getTotalLength(){
    return (length + margin);
  }//end getTotalLength()
  //-----------------------------------------------------//
 
  public double getTotalWidth(){
    return (width + margin);
  }//end getTotalWidth()
  //-----------------------------------------------------//
  
  public double getTotalCost(){
    return (
     (((length+margin) * (width+margin))*costPerSqFt)/144);
  }//end getTotalCost()

 

בכך תם הדיון במחלקת Canvas.

 

כעת נותר עוד לדון במחלקת WoodenFrame.

 

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

 

·       length

·       width

·       costPerInch

 

שים לב, ש‑length ו‑width הם האורך והרוחב של הציור, והם זהים לאורך ולרוחב של המסגרת הגמורה. costPerInch הוא עלות העץ הדרוש לבניית המסגרת, והיא נמדדת באינטשים של אורכו של לוח העץ הגולמי.

 

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

 

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

 

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

 

·       העלות הכוללת של העץ

 

קטע הקוד הבא מביא את תחילתה של המחלקה ואת שלושת משתני המופע.

 

class WoodenFrame{
  private double length; //of the painting  
  private double width; //of the painting
  private double costPerInch; //for the wood

 

מתודות-שינוי משמשות לקביעת ערכיהם של משתני המופע, כמתואר בקטע הקוד הבא.

 

  public void setLength(double length){
    this.length = length;
  }//end setLength()
  //-----------------------------------------------------//
  
  public void setWidth(double width){
    this.width = width;
  }//end setWidth()
  //-----------------------------------------------------//
  
  public void setCostPerInch(double costPerInch){
    this.costPerInch = costPerInch;
  }//end setCostPerInch()

 

 

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

 

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

 

העלות הכוללת היא מכפלת האורך הכולל (באינטשים) ב‑costPerInch של העץ.

 

  public double getTotalLengthToBuy(){
    return (2*(length + width));
  }//end getTotalLengthToBuy()
  //-----------------------------------------------------//
  
  public double getTotalCost(){
    return ((2*(length + width))*costPerInch);
  }//end getTotalCost()

 

בכך תם הדיון במחלקת WoodenFrame .

 

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

 

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

 

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

 

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

 

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

 05-01-04 / 18:23  נוצר ע"י רונית רייכמן  בתאריך 
 תֶכֶן מונחה-עצמים - בעיית בד הציור - הקודםהבא - התוכנית 
תגובות הקוראים    תגובות  -  0
דרכונט
מהי מערכת הדרכונט?
אינך מחובר, להתחברות:
דוא"ל
ססמא
נושאי לימוד
חיפוש  |  לא פועל
משלנו  |  לא פועל
גולשים מקוונים: 4