Menu
Coddy logo textTech

ממשק כחוזה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 27 מתוך 107.

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

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

type DataSource interface {
    FetchData() string
}

func ProcessData(src DataSource) {
    data := src.FetchData()
    fmt.Println("Processing:", data)
}

לפונקציה ProcessData לא משנה אם היא מקבלת חיבור למסד נתונים, לקוח API או קורא קבצים. היא רק דורשת שהקלט יוכל לבצע FetchData(). כל טיפוס שמקיים את החוזה הזה מתאים.

type Database struct{ ConnectionString string }
func (d Database) FetchData() string { return "data from DB" }

type APIClient struct{ Endpoint string }
func (a APIClient) FetchData() string { return "data from API" }

func main() {
    db := Database{ConnectionString: "localhost"}
    api := APIClient{Endpoint: "https://api.example.com"}
    
    ProcessData(db)   // עובד!
    ProcessData(api)  // עובד גם!
}

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

challenge icon

אתגר

קל

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

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

  • notifiers.go: הגדירו ממשק Notifier עם מתודה אחת Notify(message string) string. לאחר מכן צרו שלוש מבנים שונים שעומדים בחוזה הזה:
    • ConsoleNotifier עם שדה Prefix
    • FileNotifier עם שדה Filename
    • WebhookNotifier עם שדה URL
    כל מבנה צריך לממש את המתודה Notify ולהחזיר מחרוזת שמתארת כיצד ההתראה תישלח.
  • main.go: צרו פונקציה בשם BroadcastAlert שמקבלת מערך של ערכי Notifier ומחרוזת הודעה. הפונקציה צריכה לקרוא ל-Notify בכל אחד מהמתריעים ולהדפיס את התוצאות. קראו את ההגדרות מהקלט, צרו את שלושת סוגי המתריעים ושדרו התראה דרך כולם.

הקלטים הבאים יסופקו:

  • שורה 1: קידומת למסוף
  • שורה 2: שם הקובץ
  • שורה 3: כתובת URL של webhook
  • שורה 4: הודעת התראה

מתודות ה-Notify שלכם צריכות להחזיר מחרוזות בפורמטים הבאים:

  • ConsoleNotifier: [Prefix] [message]
  • FileNotifier: Writing to [Filename]: [message]
  • WebhookNotifier: POST [URL]: [message]

לדוגמה, עבור ALERT:, log.txt, https://hooks.example.com ו-Server down!, הפלט שלכם צריך להיות:

ALERT: Server down!
Writing to log.txt: Server down!
POST https://hooks.example.com: Server down!

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

נסו בעצמכם

package main

import (
	"bufio"
	"fmt"
	"os"
)

// BroadcastAlert שולחת הודעה דרך כל אובייקטי ההתראה
// TODO: יש לממש את הפונקציה כך שתבצע את הפעולות הבאות:
// - תקבל פרוסה של ערכי Notifier ומחרוזת הודעה
// - תקרא ל־Notify בכל אובייקט התראה ותדפיס את התוצאות
func BroadcastAlert(notifiers []Notifier, message string) {
	// TODO: יש לעבור על אובייקטי ההתראה ולהדפיס את התוצאה של כל התראה
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// קרא את הקידומת למסוף
	scanner.Scan()
	prefix := scanner.Text()
	
	// קרא את שם הקובץ
	scanner.Scan()
	filename := scanner.Text()
	
	// קרא את כתובת ה־URL של ה־webhook
	scanner.Scan()
	url := scanner.Text()
	
	// קרא את הודעת ההתראה
	scanner.Scan()
	message := scanner.Text()
	
	// TODO: יש ליצור מופעים של כל שלושת סוגי אובייקטי ההתראה
	// - ConsoleNotifier עם הקידומת
	// - FileNotifier עם שם הקובץ
	// - WebhookNotifier עם ה-URL
	
	// TODO: צרו slice של Notifier המכיל את כל שלושת מנגנוני ההתראה
	
	// TODO: קראו ל-BroadcastAlert עם מנגנוני ההתראה וההודעה
	
	_ = prefix
	_ = filename
	_ = url
	_ = message
	fmt.Println("TODO: Implement the solution")
}
quiz iconבחנו את עצמכם

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

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

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