Menu
Coddy logo textTech

הרכבת ממשקים

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

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

type Reader interface {
    Read() string
}

type Writer interface {
    Write(data string)
}

// ReadWriter משלב את שני הממשקים
type ReadWriter interface {
    Reader
    Writer
}

הממשק ReadWriter דורש כעת גם את המתודות Read() וגם Write(). כל טיפוס שמממש את שתי המתודות מקיים את ReadWriter, וכן את Reader ואת Writer בנפרד.

type File struct {
    Name string
}

func (f File) Read() string       { return "file content" }
func (f File) Write(data string)  { fmt.Println("Writing:", data) }

func Process(rw ReadWriter) {
    content := rw.Read()
    rw.Write(content)
}

func main() {
    f := File{Name: "data.txt"}
    Process(f)  // File מממש את ReadWriter
}

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

challenge icon

אתגר

קל

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

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

  • media.go: הגדר שלושה ממשקים ומבנה שמממש את כולם:
    • ממשק Player עם מתודה Play() string
    • ממשק Recorder עם מתודה Record(content string) string
    • ממשק MediaDevice שמורכב גם מ־Player וגם מ־Recorder
    • מבנה SmartDevice עם שדה Name, שמממש את כל המתודות הנדרשות
  • main.go: צור פונקציות שמדגימות כיצד ניתן להשתמש באותו SmartDevice דרך טיפוסי ממשקים שונים. כתוב שלוש פונקציות:
    • UsePlayer שמקבלת Player וקוראת למתודה Play שלו
    • UseRecorder שמקבלת Recorder ומחרוזת תוכן, ואז קוראת ל־Record
    • UseMediaDevice שמקבלת MediaDevice ומחרוזת תוכן, ואז קוראת גם ל־Record וגם ל־Play
    קרא את שם המכשיר ואת התוכן מהקלט, צור SmartDevice, והדגם שימוש בו דרך כל שלושת טיפוסי הממשקים.

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

  • שורה 1: שם המכשיר
  • שורה 2: תוכן להקלטה

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

  • Play(): [Name] is playing
  • Record(content): [Name] recorded: [content]

לדוגמה, עבור MyPhone ו־voice memo, הפלט שלך צריך להיות:

MyPhone is playing
MyPhone recorded: voice memo
MyPhone recorded: voice memo
MyPhone is playing

שתי השורות הראשונות מציגות את המכשיר בשימוש דרך הממשקים הנפרדים (Player ו־Recorder). שתי השורות האחרונות מציגות את השימוש בו דרך ממשק MediaDevice המורכב, שדורש את שתי היכולות. שים לב שאותו SmartDevice שלך מממש את כל שלושת הממשקים, משום שיש לו את שתי המתודות הנדרשות.

נסו בעצמכם

package main

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

// TODO: ממשו את UsePlayer שמקבלת Player וקוראת למתודה Play שלו
// עליה להדפיס את התוצאה של Play()

// TODO: ממשו את UseRecorder שמקבלת Recorder ומחרוזת content
// עליה להדפיס את התוצאה של Record(content)

// TODO: ממשו את UseMediaDevice שמקבלת MediaDevice ומחרוזת content
// עליה להדפיס את התוצאה של Record(content) ולאחר מכן של Play()

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	scanner.Scan()
	deviceName := scanner.Text()
	
	scanner.Scan()
	content := scanner.Text()
	
	// TODO: צרו SmartDevice עם השם הנתון
	
	// TODO: השתמשו בהתקן דרך הממשק Player
	
	// TODO: השתמשו בהתקן דרך הממשק Recorder
	
	// TODO: השתמשו בהתקן דרך הממשק MediaDevice
	
	_ = deviceName
	_ = content
	fmt.Println("Implement the solution")
}
quiz iconבחנו את עצמכם

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

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

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