שילוב טיפול בחריגות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 82 מתוך 87.
אתגר
קלבואו נהפוך את מערכת ניהול הספרייה שלך לחזקה יותר באמצעות שילוב טיפול מתאים בחריגות! מערכת ספרייה אמיתית צריכה לטפל בתנאי שגיאה בצורה אלגנטית: מה קורה כשמישהו מנסה לשאול ספר שאינו קיים, או כשמשתמש מנסה לשאול יותר ספרים מהמותר? תיצור חריגות מותאמות אישית שיספקו משוב משמעותי לתרחישים האלה.
תמשיך לבנות על הקוד הקיים שלך בשישה קבצים:
Book.java: השאר את המחלקה Book עם כל הפונקציונליות הקיימת: isbn, title, author, isAvailable, borrowedBy, getDetails(), וה־getters/setters המתאימים.User.java: השאר את המחלקה User עם id, name, מערך ה־ArrayList בשם borrowedBooks, וכן borrowBook(), returnBook(), getBorrowedCount() ו־toString().LibraryException.java: צור מחלקת חריגה מותאמת אישית בסיסית בשםLibraryExceptionשיורשת מ־Exception. זו תהיה מחלקת האב לכל החריגות הספציפיות לספרייה. כלול בנאי שמקבל הודעה ומעביר אותה למחלקת האב.BookNotAvailableException.java: צור חריגה מותאמת אישית שיורשת מ־LibraryException. יש לזרוק את החריגה הזאת כשמישהו מנסה לשאול ספר שכבר הושאל. כלול בנאי שמקבל את ה־ISBN של הספר ויוצר הודעה ברורה כמוBook not available: [isbn].Library.java: עדכן את המחלקה Library כך שתזרוק חריגות במקום להדפיס הודעות שגיאה. שנה את המתודהborrowBook(String userId, String isbn)כך ש:- תזרוק
LibraryExceptionעם ההודעהUser not found: [userId]אם המשתמש לא קיים - תזרוק
LibraryExceptionעם ההודעהBook not found: [isbn]אם הספר לא קיים - תזרוק
BookNotAvailableExceptionאם הספר כבר הושאל - במקרה של הצלחה, תשאיל את הספר למשתמש ותחזיר את הודעת האישור
[userName] borrowed [bookTitle]
שנה את חתימת המתודה ל־
throws LibraryExceptionושנה את סוג הערך המוחזר ל־String.השאר את כל שאר המתודות (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) פועלות כפי שפעלו קודם.
- תזרוק
Main.java: הדגם את הטיפול בחריגות! תקבל מחרוזת של פקודות המופרדות בפסיקים. כל פקודה תהיה באחד מהפורמטים האלה:ADD_BOOK:isbn:title:authorREGISTER_USER:id:nameBORROW:userId:isbn
עבד כל פקודה. עבור ADD_BOOK, הדפס
Added: [title]. עבור REGISTER_USER, הדפסRegistered: [name]. עבור פקודות BORROW, השתמש בבלוק try-catch לטיפול בחריגות; במקרה של הצלחה, הדפס את הודעת האישור, ובמקרה של כלLibraryException, הדפסError: [exception message].לאחר עיבוד כל הפקודות, הדפס
Operations completed.
תקבל קלט אחד: מחרוזת של פקודות המופרדות בפסיקים.
לדוגמה, עבור הקלט ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001, הפלט שלך יהיה:
Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completedשים לב כיצד החריגות המותאמות אישית מספקות הודעות שגיאה ברורות וספציפיות. ההשאלה הראשונה מצליחה, השנייה נכשלת כי הספר כבר הושאל (BookNotAvailableException), והשלישית נכשלת כי המשתמש U002 לא קיים (LibraryException). הגישה הזאת הופכת את מערכת הספרייה שלך לאינפורמטיבית הרבה יותר וקלה יותר לניפוי שגיאות מאשר הודעות שגיאה כלליות!
נסו בעצמכם
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// קרא את הפקודות המופרדות בפסיקים
String input = scanner.nextLine();
String[] commands = input.split(",");
// צור את Library ואת AdminService
Library library = new Library();
AdminService adminService = new AdminService(library);
// עבד כל פקודה
for (String command : commands) {
String[] parts = command.split(":");
String operation = parts[0];
if (operation.equals("ADD_BOOK")) {
String isbn = parts[1];
String title = parts[2];
String author = parts[3];
if (adminService.addBook(isbn, title, author)) {
System.out.println("Added: " + title);
}
} else if (operation.equals("REMOVE_BOOK")) {
String isbn = parts[1];
if (adminService.removeBook(isbn)) {
System.out.println("Removed: " + isbn);
} else {
System.out.println("Cannot remove: " + isbn);
}
} else if (operation.equals("REGISTER_USER")) {
String id = parts[1];
String name = parts[2];
if (adminService.registerUser(id, name)) {
System.out.println("Registered: " + name);
}
} else if (operation.equals("BORROW")) {
String userId = parts[1];
String isbn = parts[2];
// TODO: השתמש בבלוק try-catch כדי לקרוא ל-library.borrowBook(userId, isbn)
// במקרה של הצלחה, הדפס את הודעת האישור שהוחזרה
// במקרה של LibraryException, הדפס "Error: " + e.getMessage()
}
}
// TODO: הדפס "Operations completed"
}
}כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותשדות (מאפיינים)מתודת הבנאיהעמסת בנאיםחזרה – מחשבון פשוט4ירושה
ירושה בסיסית (extends)מילת המפתח superדריסת מתודות (@Override)שרשור בנאיםהמחלקה Objectירושה יחידה ורב־רמתיתלמה אין ירושה מרובה של מחלקותסיכום – היררכיית עובדים7מתודות מיוחדות ומחלקת Object
מתודת toString()equals() ו-hashCode()מתודת clone()compareTo() ו-Comparableהממשק Comparatorסיכום – מיון מותאם אישית10טיפול בחריגות ב-OOP
היררכיית מחלקות החריגותחריגות מותאמות אישיתשגיאות Checked לעומת Uncheckedתבנית Try With Resourcesחזרה – משתמש מאומת13פרויקט: ניהול ספרייה
סקירת הפרויקט ותכנון UMLמחלקות ספר ולקוחמערכת השאלת ספריםפונקציונליות חיפושממשק מנהלשילוב טיפול בחריגותבדיקות ושילוב2מצייני גישה ואנקפסולציה
סקירה של רמות הגישהמתודות Getter ו-Setterהסתרת מידעמילת המפתח finalסיכום – מנהל חשבון בנק5פולימורפיזם
יסודות העמסת מתודותדריסת מתודות (בזמן ריצה)המרה כלפי מעלה וכלפי מטההאופרטור instanceofמחלקות ומתודות מופשטותסיכום – מחשבון צורות8מושגי OOP מתקדמים
הרכבה מול ירושהאגרגציה מול הרכבהמחלקות פנימיות, מקוננות ואנונימיותEnums ומתודות של EnumRecords (Java 16+)מחלקות חתומות (Java 17+)3מאפייני מחלקה וחברים סטטיים
משתני מופע לעומת משתנים סטטייםמתודות סטטיותבלוקים סטטייםקבועים (static final)סיכום — מונה ומחלקת עזר6ממשקים ומחלקות מופשטות
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםמתודות ברירת מחדל וסטטיות בממשקמחלקות מופשטות לעומת ממשקיםממשקים פונקציונלייםסיכום – מערכת תשלומיםתרגלו בעצמכם: קומפיילר Java אונליין