סיכום - מעבד תשלומים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 46 מתוך 107.
אתגר
קלבואו נבנה מערכת מלאה לעיבוד תשלומים, המשלבת את כל מושגי הפולימורפיזם מפרק זה. תיצרו אמצעי תשלום שונים שפועלים דרך ממשק אחיד, מעבד שמקבל כל אמצעי תשלום באמצעות הזרקת תלות, ותעבדו תשלומים מרובים באמצעות אוסף פולימורפי.
תארגנו את הקוד שלכם בארבעה קבצים:
payment.go: הגדירו ממשקPaymentMethodשדורש מתודהProcess(amount float64) string. זהו החוזה שכל סוגי התשלום חייבים למלא.methods.go: צרו שלושה סוגי תשלום, שכל אחד מהם מממש את הממשקPaymentMethod:CreditCardעם השדותCardNumber(מחרוזת) ו-HolderName(מחרוזת). המתודהProcessשלו מחזירהCredit Card [last 4 digits of CardNumber] charged $[amount] to [HolderName]PayPalעם שדהEmail. המתודהProcessשלו מחזירהPayPal payment of $[amount] from [Email]BankTransferעם השדותBankNameו-AccountNumber. המתודהProcessשלו מחזירהBank transfer of $[amount] via [BankName] (***[last 3 digits of AccountNumber])
processor.go: צרו מבנהPaymentProcessorשמחזיקPaymentMethod(תלות מוזרקת). כללו בנאיNewPaymentProcessorשמקבלPaymentMethod. הוסיפו מתודהExecutePayment(amount float64) stringשמעבירה את הביצוע לאמצעי התשלום שהוזרק. צרו גם פונקציהProcessAll(payments []PaymentMethod, amount float64) []stringשמעבדת את אותו סכום באמצעות כל אמצעי תשלום שבמערך ומחזירה את כל התוצאות.main.go: קראו את פרטי התשלום מהקלט, צרו את שלושת סוגי התשלום והדגימו הן הזרקת תלות והן אוספים פולימורפיים. תחילה, השתמשו ב-NewPaymentProcessorעם כרטיס האשראי ובצעו תשלום. לאחר מכן, אספו את כל שלושת אמצעי התשלום במערך והשתמשו ב-ProcessAllכדי לעבד את כולם עם סכום שני. הדפיסו כל תוצאה בשורה נפרדת.
הקלטים הבאים יסופקו:
- שורה 1: מספר כרטיס אשראי (למשל,
4532015112830366) - שורה 2: שם בעל הכרטיס
- שורה 3: כתובת אימייל של PayPal
- שורה 4: שם הבנק
- שורה 5: מספר חשבון (למשל,
987654321) - שורה 6: סכום התשלום הראשון (עבור מעבד יחיד)
- שורה 7: סכום התשלום השני (עבור עיבוד באצווה)
עצבו את הסכומים עם שתי ספרות אחרי הנקודה העשרונית. לדוגמה, עבור 4532015112830366, John Smith, john@email.com, Chase, 987654321, 99.99 ו-50, הפלט שלכם צריך להיות:
Credit Card 0366 charged $99.99 to John Smith
Credit Card 0366 charged $50.00 to John Smith
PayPal payment of $50.00 from john@email.com
Bank transfer of $50.00 via Chase (***321)השורה הראשונה מציגה את התשלום היחיד דרך המעבד שהוזרקה אליו תלות. שלוש השורות הנותרות מציגות את העיבוד באצווה דרך האוסף הפולימורפי: אותה פונקציה ProcessAll מטפלת בכל סוגי התשלום באופן אחיד, ומדגימה כיצד ממשקים מאפשרים מערכות תשלום גמישות וניתנות להרחבה.
נסו בעצמכם
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// קראו את הקלט
cardNumber, _ := reader.ReadString('\n')
cardNumber = strings.TrimSpace(cardNumber)
holderName, _ := reader.ReadString('\n')
holderName = strings.TrimSpace(holderName)
email, _ := reader.ReadString('\n')
email = strings.TrimSpace(email)
bankName, _ := reader.ReadString('\n')
bankName = strings.TrimSpace(bankName)
accountNumber, _ := reader.ReadString('\n')
accountNumber = strings.TrimSpace(accountNumber)
amount1Str, _ := reader.ReadString('\n')
amount1Str = strings.TrimSpace(amount1Str)
amount1, _ := strconv.ParseFloat(amount1Str, 64)
amount2Str, _ := reader.ReadString('\n')
amount2Str = strings.TrimSpace(amount2Str)
amount2, _ := strconv.ParseFloat(amount2Str, 64)
// TODO: צרו את שלושת סוגי התשלום (CreditCard, PayPal, BankTransfer)
// TODO: צרו PaymentProcessor עם כרטיס האשראי באמצעות NewPaymentProcessor
// ובצעו תשלום עם amount1, ואז הדפיסו את התוצאה
// TODO: צרו slice של PaymentMethod המכיל את כל שלושת סוגי התשלום
// TODO: השתמשו ב-ProcessAll כדי לעבד את כל התשלומים עם amount2
// והדפיסו כל תוצאה בשורה נפרדת
}
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין