نظام الاستعارة
جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 79 من 87.
التحدي
سهللنواصل بناء نظام إدارة المكتبة من خلال إنشاء نظام استعارة مناسب باستخدام الفئة Library التي تدير مجموعة الكتب والمستخدمين. هنا يبدأ نظامك في الشعور بأنه مكتبة حقيقية: تتبّع من لديه ماذا وفرض قواعد الاستعارة!
ستنظّم شيفرتك عبر أربعة ملفات:
Book.java: احتفظ بفئة Book من التحدي السابق بكل وظائفها: isbn وtitle وauthor وisAvailable وborrowedBy وgetDetails()، بالإضافة إلى دوال getter/setter المناسبة.User.java: احتفظ بفئة User التي تتضمن id وname وArrayList borrowedBooks، بالإضافة إلى borrowBook() وreturnBook() وgetBorrowedCount() وtoString().Library.java: أنشئ الفئة المركزيةLibraryالتي تدير كل شيء. يجب أن تحتفظ مكتبتك بمجموعتي ArrayList: واحدة لكائناتBookوأخرى لكائناتUser. أدرج هذه الدوال:addBook(Book book)- تضيف كتابًا إلى مجموعة المكتبة.registerUser(User user)- تضيف مستخدمًا إلى المستخدمين المسجلين في المكتبة.findBookByIsbn(String isbn)- تبحث في الكتب وتُرجع Book المطابق لـ ISBN، أوnullإذا لم يتم العثور عليه.findUserById(String id)- تبحث في المستخدمين وتُرجع User المطابق للمعرّف ID، أوnullإذا لم يتم العثور عليه.borrowBook(String userId, String isbn)- تعثر على المستخدم والكتاب، ثم إذا كان كلاهما موجودًا وكان الكتاب متاحًا، تجعل المستخدم يستعير الكتاب وتطبع[userName] borrowed [bookTitle]. إذا لم يكن الكتاب متاحًا، اطبعBook not available. إذا لم يتم العثور على المستخدم أو الكتاب، اطبعInvalid user or book.returnBook(String userId, String isbn)- تعثر على المستخدم والكتاب، ثم تجعل المستخدم يعيد الكتاب وتطبع[userName] returned [bookTitle]. إذا لم يتم العثور على المستخدم أو الكتاب، اطبعInvalid user or book.Main.java: اجمع مكوّنات نظام المكتبة معًا! ستتلقى مدخلات لكتابين، يتضمن كل منهما ISBN والعنوان وauthor، ولمستخدم واحد يتضمن ID والاسم، ثم سلسلة من العمليات.أنشئ Library، وأضف الكتابين، وسجّل المستخدم. ثم عالج العمليات: ستتلقى سلسلة مفصولة بفواصل، حيث تكون صيغة كل عملية
borrow:userId:isbnأوreturn:userId:isbn.بعد معالجة جميع العمليات، اطبع ملخصًا يعرض حالة كل كتاب بالصيغة
[isbn]: [Available/Borrowed].
ستتلقى المدخلات بهذا الترتيب: ISBN الخاص بـ book1، وعنوان book1، وauthor الخاص بـ book1، ثم ISBN الخاص بـ book2، وعنوان book2، وauthor الخاص بـ book2، ثم معرّف المستخدم، واسم المستخدم، وأخيرًا سلسلة العمليات.
على سبيل المثال، باستخدام المدخلات ISBN-001 وClean Code وRobert Martin وISBN-002 وDesign Patterns وGang of Four وU001 وAlice وborrow:U001:ISBN-001,borrow:U001:ISBN-002,return:U001:ISBN-001، سيكون الناتج:
Alice borrowed Clean Code
Alice borrowed Design Patterns
Alice returned Clean Code
ISBN-001: Available
ISBN-002: Borrowedيجمع هذا التحدي بين التركيب والتغليف وتصميم الدوال لإنشاء نظام متكامل. تعمل فئة Library كمنسّق، إذ تفوّض منطق الاستعارة الفعلي إلى فئتي User وBook، مع إدارة المجموعة بأكملها!
جرّب بنفسك
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// قراءة معلومات الكتاب 1
String isbn1 = scanner.nextLine();
String title1 = scanner.nextLine();
String author1 = scanner.nextLine();
// قراءة معلومات الكتاب 2
String isbn2 = scanner.nextLine();
String title2 = scanner.nextLine();
String author2 = scanner.nextLine();
// قراءة معلومات المستخدم
String userId = scanner.nextLine();
String userName = scanner.nextLine();
// قراءة نص العمليات (مفصولة بفاصلة، الصيغة: borrow:userId:isbn أو return:userId:isbn)
String operationsStr = scanner.nextLine();
// TODO: إنشاء كائنات Book لـ book1 و book2
// TODO: إنشاء كائن User
// TODO: إنشاء Library وإضافة كلا الكتابين وتسجيل المستخدم
// TODO: تقسيم operationsStr باستخدام "," ومعالجة كل عملية
// لكل عملية، قم بالتقسيم باستخدام ":" للحصول على action و userId و isbn
// استدعاء library.borrowBook() أو library.returnBook() وفقًا لذلك
// TODO: طباعة ملخص لكل كتاب بالتنسيق "[isbn]: [Available/Borrowed]"
}
}جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةمقدمة في الـ OOPالفئات (Classes) مقابل الكائنات (Objects)الكلمة المفتاحية thisالدوال (Methods)الحقول (Attributes)دالة البناء (Constructor)تعدد أشكال دالة البناء (Constructor Overloading)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسية (extends)الكلمة المفتاحية superإعادة تعريف الدوال (@Override)تسلسل المنشئات (Constructor Chaining)كلاس Objectالوراثة الأحادية ومتعددة المستوياتلماذا لا توجد وراثة متعددة للكلاساتمراجعة - هيكلية الموظفين7الدوال الخاصة وفئة Object
دالة toString()equals() و hashCode()دالة clone()compareTo() و Comparableواجهة Comparatorمراجعة - الترتيب المخصص10معالجة الاستثناءات في OOP
التسلسل الهرمي لفئات الاستثناءاتالاستثناءات المخصصةالأخطاء من نوع Checked مقابل Uncheckedنمط Try With Resourcesمراجعة - Validated User13مشروع: إدارة المكتبة
نظرة عامة على المشروع وتصميم UMLفئات الكتاب والمستخدمنظام الاستعارةخاصية البحثواجهة المسؤولدمج معالجة الاستثناءاتالاختبار والدمج2محددات الوصول والتغليف
نظرة عامة على مستويات الوصولدوال Getter و Setterإخفاء البياناتالكلمة المفتاحية finalمراجعة - مدير الحساب البنكي5تعدد الأشكال (Polymorphism)
أساسيات الـ Method Overloadingالـ Method Overriding (في وقت التشغيل)الـ Upcasting والـ Downcastingمعامل الـ instanceofالفئات والدوال المجردة (Abstract)مراجعة - حاسبة الأشكال8مفاهيم OOP المتقدمة
الـ Composition مقابل الـ Inheritanceالـ Aggregation مقابل الـ Compositionالفئات الداخلية والمتداخلة والمجهولة (Inner, Nested & Anonymous)الـ Enums ودوالهاالـ Records (Java 16+)الـ Sealed Classes (Java 17+)11أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Builderنمط Observerنمط Strategy3خصائص الفئة والعضو الساكن
المتغيرات الخاصة بالكائن مقابل المتغيرات الساكنةالدوال الساكنةالكتل البرمجية الساكنةالثوابت (static final)ملخص - العداد والأدوات المساعدة6الواجهات (Interfaces) والأصناف المجردة (Abstract Classes)
مقدمة في الواجهات (Interfaces)تنفيذ الواجهات (Interfaces)تنفيذ واجهات متعددةالـ Default و Static في الواجهاتالأصناف المجردة مقابل الواجهاتالواجهات الوظيفية (Functional Interfaces)مراجعة - نظام الدفع9الأنواع العامة (Generics)
مقدمة في الأنواع العامةالأصناف العامة (Generic Classes)الدوال العامة (Generic Methods)معاملات الأنواع المقيدةالرموز البديلة (?, extends, super)مراجعة - الحاويات العامة12أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المكررتدرّب بنفسك: مترجم Java عبر الإنترنت