Menu
Coddy logo textTech

תבנית המתאם

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 57 מתוך 70.

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

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

// מחלקה קיימת עם ממשק לא תואם
public class OldPrinter
{
    public void PrintMessage(string msg) => Console.WriteLine($"Old: {msg}");
}

// הממשק שהקוד שלך מצפה לו
public interface IPrinter
{
    void Print(string text);
}

// המתאם מגשר על הפער
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter;
    
    public PrinterAdapter(OldPrinter oldPrinter)
    {
        _oldPrinter = oldPrinter;
    }
    
    public void Print(string text)
    {
        _oldPrinter.PrintMessage(text);  // מעביר את הקריאה לממשק הישן
    }
}

עכשיו הקוד שלך יכול לעבוד עם המדפסת הישנה דרך הממשק הצפוי:

OldPrinter legacy = new OldPrinter();
IPrinter printer = new PrinterAdapter(legacy);

printer.Print("Hello");  // Old: Hello

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

challenge icon

אתגר

קל

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

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

  • LegacyAudio.cs: הקובץ הזה מייצג ספרייה קיימת שאי אפשר לשנות. צור מחלקה בשם LegacyAudioPlayer במרחב השמות MediaSystem, עם מתודה PlayMp3(string filename) שמחזירה את המחרוזת "Playing MP3: {filename}". זהו ה־"adaptee" שלך — המחלקה עם הממשק שאינו תואם.
  • MediaAdapter.cs: צור את הממשק ואת המתאם באותו מרחב שמות. הגדר ממשק בשם IMediaPlayer עם מתודה Play(string filename) שמחזירה מחרוזת. לאחר מכן צור מחלקה בשם MediaPlayerAdapter שמממשת את IMediaPlayer. המתאם שלך צריך לעטוף מופע של LegacyAudioPlayer (שמועבר דרך הבנאי) ולתרגם את הקריאה ל־Play לקריאה למתודה PlayMp3 של הנגן הישן.
  • Program.cs: חבר את כל החלקים יחד: צור את הנגן הישן, עטוף אותו במתאם שלך והשתמש במתאם דרך הממשק IMediaPlayer. כך מודגם איך קוד הלקוח יכול לעבוד עם הממשק המודרני, בזמן שהמתאם מטפל בתקשורת עם המערכת הישנה מאחורי הקלעים.

תקבל קלט אחד:

  • שם הקובץ לניגון (לדוגמה, song.mp3)

צור מופע של LegacyAudioPlayer, עטוף אותו ב־MediaPlayerAdapter, ואז קרא ל־Play במתאם באמצעות הממשק IMediaPlayer והדפס את התוצאה.

לדוגמה, אם הקלט הוא favorite_track.mp3, הפלט אמור להיות:

Playing MP3: favorite_track.mp3

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

נסו בעצמכם

using System;
using MediaSystem;

class Program
{
    public static void Main(string[] args)
    {
        // קרא את שם הקובץ שהוזן
        string filename = Console.ReadLine();
        
        // TODO: צור מופע של LegacyAudioPlayer
        
        // TODO: עטוף אותו ב-MediaPlayerAdapter
        
        // TODO: השתמש במתאם דרך הממשק IMediaPlayer
        // והדפס את התוצאה של הקריאה ל-Play עם שם הקובץ
    }
}
quiz iconבחנו את עצמכם

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

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

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