Menu
Coddy logo textTech

מיקסינים לעומת ממשק

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 55 מתוך 110.

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

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

// גישת הממשק - יש לממש הכול בעצמכם
abstract class Printable {
  void printInfo();
}

class Report implements Printable {
  @override
  void printInfo() {
    print('Printing report...');  // את זה אתם כותבים
  }
}

// גישת ה־Mixin - המימוש כלול
mixin Printable {
  void printInfo() {
    print('Printing...');  // כבר נכתב עבורכם
  }
}

class Report with Printable {}  // מקבל את printInfo() אוטומטית

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

תכונהממשקמיקסין
מספקחוזה בלבדחוזה + קוד
מימושאתה כותב אותוכלול
מילת מפתחimplementswith
הכי מתאים ל־התנהגויות שונות, אותו APIהתנהגות משותפת

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

class MyClass with SomeMixin implements SomeInterface {
  // with מופיע לפני implements
}
challenge icon

אתגר

קל

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

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

  • notifiable.dart: הגדירו מחלקה מופשטת Notifiable שמשמשת כממשק. עליה להצהיר על שתי מתודות מופשטות: send(String message) ו-getChannel(), שמחזירה String. סוגי התראות שונים יממשו את המתודות האלה בדרכים שונות בהתאם לערוץ הספציפי שלהם.
  • logging.dart: צרו מיקסין בשם Logging שמספק התנהגות משותפת שכל ההתראות אמורות לכלול. כללו מתודה logSent(String channel, String message) שמדפיסה [LOG] Sent via [channel]: [message] ומתודה logTimestamp() שמדפיסה [LOG] Timestamp recorded. ההתנהגות הזאת זהה בכל סוגי ההתראות, ולכן היא מתאימה במיוחד למיקסין.
  • main.dart: ייבאו את שני הקבצים וצרו שתי מחלקות התראה שמשלבות את הממשק עם המיקסין:
    • מחלקה EmailNotification שמשתמשת במיקסין Logging ומממשת את Notifiable. המתודה getChannel() שלה אמורה להחזיר 'Email', והמתודה send() שלה אמורה להדפיס Sending email: [message], ואז לקרוא ל-logSent() עם הערוץ וההודעה, ואז לקרוא ל-logTimestamp()
    • מחלקה SMSNotification שמשתמשת במיקסין Logging ומממשת את Notifiable. המתודה getChannel() שלה אמורה להחזיר 'SMS', והמתודה send() שלה אמורה להדפיס Sending SMS: [message], ואז לקרוא ל-logSent() עם הערוץ וההודעה, ואז לקרוא ל-logTimestamp()
    לאחר מכן, צרו מופע של EmailNotification וקראו ל-send('Hello World'), הדפיסו שורה ריקה, צרו מופע של SMSNotification וקראו ל-send('Quick update')

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

פלט צפוי:

Sending email: Hello World
[LOG] Sent via Email: Hello World
[LOG] Timestamp recorded

Sending SMS: Quick update
[LOG] Sent via SMS: Quick update
[LOG] Timestamp recorded

נסו בעצמכם

import 'notifiable.dart';
import 'logging.dart';

// TODO: צרו מחלקה EmailNotification ש:
//       - משתמשת ב-mixin ‏Logging (with)
//       - מממשת את Notifiable (implements)
//       - getChannel() מחזירה 'Email'
//       - send() מדפיסה 'Sending email: [message]', ואז קוראת ל-logSent(), ואז ל-logTimestamp()

// TODO: צרו מחלקה SMSNotification ש:
//       - משתמשת ב-mixin ‏Logging (with)
//       - מממשת את Notifiable (implements)
//       - getChannel() מחזירה 'SMS'
//       - send() מדפיסה 'Sending SMS: [message]', ואז קוראת ל-logSent(), ואז ל-logTimestamp()

void main() {
  // TODO: צרו EmailNotification וקראו ל-send('Hello World')
  
  // TODO: הדפיסו שורה ריקה
  
  // TODO: צרו SMSNotification וקראו ל-send('Quick update')
}
quiz iconבחנו את עצמכם

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

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

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