Menu
Coddy logo textTech

מבוא לתבניות עיצוב

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

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

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

קטגוריהמטרהדוגמאות
יצירתייםמנגנונים ליצירת אובייקטיםSingleton, Factory, Builder
מבנייםהרכבת טיפוסים למבנים גדולים יותרAdapter, Decorator, Composite
התנהגותייםתקשורת בין אובייקטיםObserver, Strategy, Command

ב-Go, דפוסי עיצוב נראים אחרת מאשר בשפות OOP מסורתיות.

בלי מחלקות או ירושה, Go מממשת תבניות באמצעות ממשקים, הטמעת מבנים והרכבה. למשל, במקום שבו Java עשויה להשתמש במחלקה מופשטת, Go משתמשת בממשק. במקום שבו C++ עשויה להשתמש בירושה, Go משתמשת בהטמעה.

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

בשיעורים הבאים תממשו כמה דפוסים בסיסיים ב-Go, החל בדפוסים יצירתיים כמו Singleton ו-Factory, ולאחר מכן תעברו לדפוסים התנהגותיים כמו Observer ו-Strategy.

challenge icon

אתגר

קל

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

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

  • notifier.go: הגדירו את הממשק המרכזי ואת הטיפוסים עבור מערכת ההתראות שלכם.

    צרו ממשק Notifier עם מתודה יחידה Send(message string) string שמחזירה הודעת אישור.

    ממשו שני טיפוסי התראות קונקרטיים:

    • EmailNotifier עם שדה Address. המתודה Send שלו מחזירה Email to [address]: [message]
    • SMSNotifier עם שדה PhoneNumber. המתודה Send שלו מחזירה SMS to [phone]: [message]
  • dispatcher.go: צרו מפיץ שפועל עם כל notifier באמצעות הממשק.

    בנו מבנה NotificationDispatcher שמכיל פרוסה של ממשקי Notifier. הוסיפו את המתודות הבאות:

    • AddNotifier(n Notifier) כדי לרשום notifier
    • Broadcast(message string) []string ששולחת את ההודעה באמצעות כל ה-notifiers הרשומים ומחזירה פרוסה של כל מחרוזות האישור

    צרו גם בנאי NewNotificationDispatcher() שמחזיר מפיץ מאותחל.

  • main.go: הגדירו notifiers ושדרו הודעות.

    קראו את מספר ה-notifiers ליצירה. עבור כל notifier, קראו את הטיפוס שלו (email או sms) ואת היעד שלו (כתובת או מספר טלפון). הוסיפו כל אחד למפיץ.

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

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

  • שורה 1: מספר ה-notifiers
  • עבור כל notifier: הטיפוס (email או sms), ולאחר מכן היעד
  • השורה האחרונה: הודעה לשידור

לדוגמה, בהינתן:

3
email
alice@example.com
sms
555-1234
email
bob@example.com
Server maintenance at midnight

הפלט שלכם צריך להיות:

Email to alice@example.com: Server maintenance at midnight
SMS to 555-1234: Server maintenance at midnight
Email to bob@example.com: Server maintenance at midnight

ובהינתן:

2
sms
555-9999
sms
555-0000
Meeting canceled

הפלט שלכם צריך להיות:

SMS to 555-9999: Meeting canceled
SMS to 555-0000: Meeting canceled

המבנה הזה מדגים כיצד ממשקים מאפשרים תכנונים גמישים וניתנים להרחבה. המפיץ לא מכיר את טיפוסי ההתראות הספציפיים. הוא רק יודע שהם יכולים לבצע Send. זהו הבסיס שעליו נשענים דפוסים כמו Observer ו-Strategy!

נסו בעצמכם

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// קרא את מספר אמצעי ההתראה
	countStr, _ := reader.ReadString('\n')
	count, _ := strconv.Atoi(strings.TrimSpace(countStr))

	// צור מפיץ חדש
	dispatcher := NewNotificationDispatcher()

	// קרא כל אמצעי התראה והוסף אותו למפיץ
	for i := 0; i < count; i++ {
		notifierType, _ := reader.ReadString('\n')
		notifierType = strings.TrimSpace(notifierType)

		destination, _ := reader.ReadString('\n')
		destination = strings.TrimSpace(destination)

		// TODO: צור את אמצעי ההתראה המתאים בהתאם לסוג
		// והוסף אותו למפיץ
		// רמז: בדוק אם notifierType הוא "email" או "sms"

	}

	// קרא את ההודעה להפצה
	message, _ := reader.ReadString('\n')
	message = strings.TrimSpace(message)

	// TODO: הפץ את ההודעה והדפס כל אישור

}
quiz iconבחנו את עצמכם

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

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

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