ممارسة: البرمجة الكائنية

هذا الدرس هو تطبيق عملي للمرحلة الثالثة، يجمع بين التغليف والوراثة وتعدد الأشكال والواجهات.

متطلبات المشروع

بناء نظام إدارة مكتبة يدعم:

الكود الكامل

JAVA
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

// واجهة قابل للبحث
public interface Searchable {
    boolean matches(String keyword);
}

// فئة Book
public class Book implements Searchable {
    private String isbn;
    private String title;
    private String author;
    private boolean isBorrowed;
    
    public Book(String isbn, String title, String author) {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
        this.isBorrowed = false;
    }
    
    public String getIsbn() { return isbn; }
    public String getTitle() { return title; }
    public String getAuthor() { return author; }
    public boolean isBorrowed() { return isBorrowed; }
    
    public void borrow() {
        if (!isBorrowed) {
            isBorrowed = true;
        } else {
            throw new IllegalStateException("الكتاب معار بالفعل");
        }
    }
    
    public void returnBook() {
        isBorrowed = false;
    }
    
    @Override
    public boolean matches(String keyword) {
        String lower = keyword.toLowerCase();
        return title.toLowerCase().contains(lower) || 
               author.toLowerCase().contains(lower) ||
               isbn.contains(keyword);
    }
    
    @Override
    public String toString() {
        String status = isBorrowed ? "[معار]" : "[متاح]";
        return status + " " + title + " - " + author + " (" + isbn + ")";
    }
}

// فئة Member
public class Member implements Searchable {
    private String id;
    private String name;
    private List<Book> borrowedBooks;
    
    public Member(String id, String name) {
        this.id = id;
        this.name = name;
        this.borrowedBooks = new ArrayList<>();
    }
    
    public String getId() { return id; }
    public String getName() { return name; }
    public List<Book> getBorrowedBooks() { return borrowedBooks; }
    
    public void borrowBook(Book book) {
        if (borrowedBooks.size() >= 3) {
            throw new IllegalStateException("لا يمكن استعارة أكثر من 3 كتب");
        }
        book.borrow();
        borrowedBooks.add(book);
    }
    
    public void returnBook(Book book) {
        if (borrowedBooks.remove(book)) {
            book.returnBook();
        } else {
            throw new IllegalStateException("هذا الكتاب ليس معارًا لهذا العضو");
        }
    }
    
    @Override
    public boolean matches(String keyword) {
        String lower = keyword.toLowerCase();
        return name.toLowerCase().contains(lower) || id.contains(keyword);
    }
    
    @Override
    public String toString() {
        return name + " (ID: " + id + ") - كتب معارة: " + borrowedBooks.size();
    }
}

// فئة Library
public class Library {
    private List<Book> books;
    private List<Member> members;
    
    public Library() {
        this.books = new ArrayList<>();
        this.members = new ArrayList<>();
    }
    
    public void addBook(Book book) {
        books.add(book);
        System.out.println("تمت إضافة: " + book.getTitle());
    }
    
    public void addMember(Member member) {
        members.add(member);
        System.out.println("تمت إضافة العضو: " + member.getName());
    }
    
    public Book findBook(String isbn) {
        return books.stream()
            .filter(b -> b.getIsbn().equals(isbn))
            .findFirst()
            .orElse(null);
    }
    
    public Member findMember(String id) {
        return members.stream()
            .filter(m -> m.getId().equals(id))
            .findFirst()
            .orElse(null);
    }
    
    public List<Book> searchBooks(String keyword) {
        return books.stream()
            .filter(b -> b.matches(keyword))
            .collect(Collectors.toList());
    }
    
    public List<Member> searchMembers(String keyword) {
        return members.stream()
            .filter(m -> m.matches(keyword))
            .collect(Collectors.toList());
    }
    
    public void borrowBook(String isbn, String memberId) {
        Book book = findBook(isbn);
        Member member = findMember(memberId);
        
        if (book == null) {
            System.out.println("الكتاب غير موجود");
            return;
        }
        if (member == null) {
            System.out.println("العضو غير موجود");
            return;
        }
        
        try {
            member.borrowBook(book);
            System.out.println(member.getName() + " استعار: " + book.getTitle());
        } catch (IllegalStateException e) {
            System.out.println("خطأ: " + e.getMessage());
        }
    }
    
    public void returnBook(String isbn, String memberId) {
        Book book = findBook(isbn);
        Member member = findMember(memberId);
        
        if (book == null || member == null) {
            System.out.println("كتاب أو عضو غير موجود");
            return;
        }
        
        try {
            member.returnBook(book);
            System.out.println(member.getName() + " أعاد: " + book.getTitle());
        } catch (IllegalStateException e) {
            System.out.println("خطأ: " + e.getMessage());
        }
    }
    
    public void printStatistics() {
        long borrowedCount = books.stream().filter(Book::isBorrowed).count();
        
        System.out.println("=== إحصائيات المكتبة ===");
        System.out.println("إجمالي الكتب: " + books.size());
        System.out.println("الكتب المتاحة: " + (books.size() - borrowedCount));
        System.out.println("الكتب المعار: " + borrowedCount);
        System.out.println("الأعضاء: " + members.size());
    }
    
    public void listAllBooks() {
        System.out.println("\n--- جميع الكتب ---");
        books.forEach(System.out::println);
    }
    
    public void listAllMembers() {
        System.out.println("\n--- جميع الأعضاء ---");
        members.forEach(System.out::println);
    }
}

// البرنامج الرئيسي
public class LibrarySystem {
    private static Library library = new Library();
    
    public static void main(String[] args) {
        // إضافة كتب
        library.addBook(new Book("978-0134685991", "Effective Java", "Joshua Bloch"));
        library.addBook(new Book("978-0596009205", "Head First Java", "Kathy Sierra"));
        library.addBook(new Book("978-0132350884", "Clean Code", "Robert C. Martin"));
        
        // إضافة أعضاء
        library.addMember(new Member("M001", "أحمد"));
        library.addMember(new Member("M002", "محمد"));
        
        // عرض الكتب
        library.listAllBooks();
        library.listAllMembers();
        
        // استعارة كتب
        library.borrowBook("978-0134685991", "M001");
        library.borrowBook("978-0596009205", "M001");
        
        // عرض الإحصائيات
        library.printStatistics();
        
        // البحث
        System.out.println("\n--- بحث عن 'Java' ---");
        library.searchBooks("Java").forEach(System.out::println);
        
        // إعادة كتاب
        library.returnBook("978-0134685991", "M001");
        
        // الإحصائيات النهائية
        library.printStatistics();
    }
}

ناتج ejemplo

TEXT
تمت إضافة: Effective Java
تمت إضافة: Head First Java
تمت إضافة: Clean Code
تمت إضافة العضو: أحمد
تمت إضافة العضو: محمد

--- جميع الكتب ---
[متاح] Effective Java - Joshua Bloch (978-0134685991)
[متاح] Head First Java - Kathy Sierra (978-0596009205)
[متاح] Clean Code - Robert C. Martin (978-0132350884)

--- جميع الأعضاء ---
أحمد (ID: M001) - كتب معارة: 0
محمد (ID: M002) - كتب معارة: 0

أحمد استعار: Effective Java
أحمد استعار: Head First Java

=== إحصائيات المكتبة ===
إجمالي الكتب: 3
الكتب المتاحة: 1
الكتب المعار: 2
الأعضاء: 2

--- بحث عن 'Java' ---
[معار] Effective Java - Joshua Bloch (978-0134685991)
[معار] Head First Java - Kathy Sierra (978-0596009205)

أحمد أعاد: Effective Java

=== إحصائيات المكتبة ===
إجمالي الكتب: 3
الكتب المتاحة: 2
الكتب المعار: 1
الأعضاء: 2

المفاهيم المستخدمة

المفهوم التطبيق
التغليف private متغيرات + getters/setters
الواجهات Searchable للبحث
Exceptions IllegalStateException للأخطاء
Collections ArrayList للكتب والأعضاء
Streams البحث والإحصائيات

❓ أسئلة شائعة

س كيف يمكن تحسين النظام؟
ج يمكن إضافة قاعدة بيانات، واجهة مستخدم رسومية، نظام إشعارات.
س لماذا نستخدم Streams للبحث؟
ج Streams تجعل الكود أكثر إيجازًا وقراءة.

📖 ملخص

📝 تمارين

  1. تحسين: أضف تاريخ الاستعارة والإعادة
  2. بحث: أضف بحث متقدم (حسب المؤلف، السنة، التصنيف)
  3. تصدير: أضف تصدير الإحصائيات إلى ملف

الدرس التالي

في الدرس التالي، سنتعلم نظرة عامة على Collections — مقدمة في هياكل البيانات.

100%