Menu
Coddy logo textTech

תבנית המתאם

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 71 מתוך 87.

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

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

// ממשק קיים שהקוד שלך משתמש בו
interface MediaPlayer {
    void play(String filename);
}

// מחלקה של צד שלישי עם ממשק לא תואם
class AdvancedVideoPlayer {
    public void playVideo(String filename) {
        System.out.println("Playing video: " + filename);
    }
}

המתאם עוטף את המחלקה שאינה תואמת ומממש את הממשק הצפוי, תוך תרגום הקריאות ביניהם:

class VideoPlayerAdapter implements MediaPlayer {
    private AdvancedVideoPlayer videoPlayer;
    
    public VideoPlayerAdapter() {
        this.videoPlayer = new AdvancedVideoPlayer();
    }
    
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

עכשיו קוד הלקוח שלך יכול להשתמש בנגן הווידאו דרך הממשק המוכר MediaPlayer:

MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4");  // פלט: מנגן סרטון: movie.mp4

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

challenge icon

אתגר

קל

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

תארגן את הקוד שלך בארבעה קבצים:

  • TemperatureProvider.java: הגדר את הממשק שיישום מזג האוויר שלך מצפה לו. עליו להצהיר על מתודה getTemperatureCelsius() שמחזירה ערך מסוג double המייצג את הטמפרטורה בצלזיוס.
  • FahrenheitSensor.java: מחלקה זו מייצגת את החיישן הישן, בעל הממשק שאינו תואם. צור מחלקה עם שדה פרטי מסוג double עבור הטמפרטורה בפרנהייט, שנקבע באמצעות הבנאי. צריכה להיות בה מתודה readFahrenheit() שמחזירה את ערך הפרנהייט השמור.
  • SensorAdapter.java: צור את המתאם שהופך את חיישן הפרנהייט לתואם ליישום מזג האוויר שלך. על המתאם שלך לממש את TemperatureProvider ולעטוף FahrenheitSensor. כשקוראים ל-getTemperatureCelsius(), עליו לקרוא את הערך מהחיישן ולהמיר אותו לצלזיוס באמצעות הנוסחה: (fahrenheit - 32) * 5 / 9.
  • Main.java: חבר את כל החלקים יחד! תקבל קלט אחד: קריאת טמפרטורה בפרנהייט (double).

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

    הדפס את התוצאה בפורמט הזה: Temperature: [celsius] C כאשר celsius מעוגל למקום אחד אחרי הנקודה העשרונית.

תקבל קלט אחד: הטמפרטורה בפרנהייט (double).

לדוגמה, עבור הקלט 98.6, הפלט יהיה:

Temperature: 37.0 C

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

נסו בעצמכם

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double fahrenheit = scanner.nextDouble();
        
        // TODO: צור FahrenheitSensor עם ערך הקלט
        
        // TODO: צור SensorAdapter שעוטף את החיישן
        
        // TODO: אחסן את המתאם במשתנה מסוג TemperatureProvider
        
        // TODO: קבל את הטמפרטורה בצלזיוס והדפס אותה
        // תבנית: "Temperature: [celsius] C" עם ספרה אחת אחרי הנקודה העשרונית
        // רמז: השתמש ב-String.format("%.1f", value) לעיצוב
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

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

תרגלו בעצמכם: קומפיילר Java אונליין