סיכום – רשומות תלמידים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 51 מתוך 107.
אתגר
קלבוא נבנה מערכת לניהול רישומי תלמידים שמדגימה כימוס נכון. תיצור מבנה לניהול תלמידים שבו נתונים אקדמיים רגישים מוגנים, תוך מתן גישה מבוקרת באמצעות מתודות שתוכננו היטב.
תארגן את הקוד שלך בשני קבצים:
student.go: צור מבנהStudentשמגן על מידע רגיש ובו בזמן חושף נתונים ציבוריים בטוחים. השדהNameשל התלמיד צריך להיות מיוצא (נגיש לציבור), אך השדותgrade(float64) ו-studentID(string) צריכים להיות לא מיוצאים כדי להגן על המידע הרגיש הזה.ממש את הדברים הבאים:
- בנאי
NewStudent(name, id string, initialGrade float64) *Studentשיוצר תלמיד. יש להגדיר את הציון ההתחלתי רק אם הוא בין 0 ל-100 (כולל); אחרת, ברירת המחדל תהיה 0. - מתודת אחזור
Grade() float64שמחזירה את הציון הנוכחי - מתודת אחזור
StudentID() stringשמחזירה את מזהה התלמיד - מתודת הצבה
SetGrade(newGrade float64) boolשמעדכנת את הציון רק אם הערך החדש בין 0 ל-100 (כולל). החזרtrueאם הציון עודכן, ו-falseאחרת. - מתודה
Summary() stringשמחזירה את התבנית:[Name] (ID: [studentID]) - Grade: [grade]
- בנאי
main.go: קרא את פרטי התלמיד מהקלט, צור תלמיד באמצעות הבנאי, ולאחר מכן בצע פעולות על הציון. הצג את סיכום התלמיד לאחר יצירתו ולאחר כל ניסיון לעדכן את הציון.
הקלט הבא יסופק:
- שורה 1: שם התלמיד
- שורה 2: מזהה התלמיד
- שורה 3: ציון התחלתי
- שורה 4: ציון חדש ראשון להצבה
- שורה 5: ציון חדש שני להצבה
לאחר יצירת התלמיד, הדפס את הסיכום שלו. לאחר מכן נסה לעדכן כל ציון; אם העדכון הצליח, הדפס את הסיכום המעודכן; אם הוא נדחה, הדפס Invalid grade rejected. עצב את כל ערכי הציון עם שתי ספרות אחרי הנקודה העשרונית.
לדוגמה, עבור Emma Wilson, STU001, 85.5, 92.0 ו-150, הפלט שלך צריך להיות:
Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejectedהעדכון האחרון נכשל משום ש-150 מחוץ לטווח התקין. מתודת ההצבה שלך אוכפת את הכלל הזה ושומרת על תקינות נתוני התלמיד. שים לב שאי אפשר לגשת ישירות אל studentID ואל grade: קוד חיצוני חייב להשתמש במתודות האחזור וההצבה שלך כדי לגשת לנתונים המוגנים האלה.
נסו בעצמכם
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// קרא את שם התלמיד
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// קרא את מזהה התלמיד
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
// קרא את הציון ההתחלתי
initialGradeStr, _ := reader.ReadString('\n')
initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)
// קרא את הציון החדש הראשון
newGrade1Str, _ := reader.ReadString('\n')
newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)
// קרא את הציון החדש השני
newGrade2Str, _ := reader.ReadString('\n')
newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)
// TODO: צור תלמיד חדש באמצעות הבנאי NewStudent
// TODO: הדפס את סיכום פרטי התלמיד לאחר יצירתו
// TODO: נסה לעדכן את הציון בפעם הראשונה
// אם העדכון הצליח, הדפס את הסיכום המעודכן
// אם העדכון נדחה, הדפס "Invalid grade rejected"
// TODO: נסה לעדכן את הציון בפעם השנייה
// אם העדכון הצליח, הדפס את הסיכום המעודכן
// אם העדכון נדחה, הדפס "Invalid grade rejected"
// רמז: השתמש ב-fmt.Sprintf עם %.2f כדי לעצב ציונים ב-Summary()
_ = newGrade1 // הסר שורה זו כשתשתמש במשתנה
_ = newGrade2 // הסר שורה זו כשתשתמש במשתנה
}
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין