Code-Alongs for Sprint 6

Overview

These code-along exercises will help you apply the concepts you've learned in this sprint. Follow along with the instructions and code examples to build your own implementations of the concepts covered.

Code-Along: Building a Library Management System

In this code-along, we'll build a library management system that demonstrates the principles of encapsulation, polymorphism, and the use of generics.

Project Structure

The library system will include the following components:

  • A LibraryItem interface that defines common behaviors
  • Abstract Item class that implements the interface
  • Concrete classes: Book, DVD, and Magazine
  • A generic Catalog<T extends LibraryItem> class to manage collections of items
  • A Library class that uses encapsulation to protect its data

Key Learning Points

  • Implementing interfaces for polymorphic behavior
  • Using encapsulation to protect library item data
  • Creating a generic catalog to handle different types of items
  • Applying primitive wrapper classes where appropriate

Getting Started

  1. Create a new Java project in your IDE
  2. Set up the package structure: com.bloomtech.library
  3. Follow the implementation steps below

Step 1: Create the LibraryItem Interface

package com.bloomtech.library;

public interface LibraryItem {
    String getTitle();
    String getUniqueId();
    boolean isAvailable();
    void checkOut();
    void checkIn();
}

Step 2: Create the Abstract Item Class

package com.bloomtech.library;

public abstract class Item implements LibraryItem {
    private final String uniqueId;
    private final String title;
    private boolean available;
    
    public Item(String uniqueId, String title) {
        this.uniqueId = uniqueId;
        this.title = title;
        this.available = true;
    }
    
    @Override
    public String getUniqueId() {
        return uniqueId;
    }
    
    @Override
    public String getTitle() {
        return title;
    }
    
    @Override
    public boolean isAvailable() {
        return available;
    }
    
    @Override
    public void checkOut() {
        if (available) {
            available = false;
        } else {
            throw new IllegalStateException("Item is already checked out");
        }
    }
    
    @Override
    public void checkIn() {
        available = true;
    }
}

Step 3: Create Concrete Classes

package com.bloomtech.library;

// Book class
public class Book extends Item {
    private final String author;
    private final String isbn;
    private final Integer pageCount;
    
    public Book(String uniqueId, String title, String author, String isbn, int pageCount) {
        super(uniqueId, title);
        this.author = author;
        this.isbn = isbn;
        this.pageCount = pageCount;
    }
    
    public String getAuthor() {
        return author;
    }
    
    public String getIsbn() {
        return isbn;
    }
    
    public Integer getPageCount() {
        return pageCount;
    }
}

// DVD class
public class DVD extends Item {
    private final String director;
    private final Integer runtime;
    
    public DVD(String uniqueId, String title, String director, int runtime) {
        super(uniqueId, title);
        this.director = director;
        this.runtime = runtime;
    }
    
    public String getDirector() {
        return director;
    }
    
    public Integer getRuntime() {
        return runtime;
    }
}

Step 4: Create a Generic Catalog Class

package com.bloomtech.library;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Catalog<T extends LibraryItem> {
    private final Map<String, T> items;
    
    public Catalog() {
        this.items = new HashMap<>();
    }
    
    public void addItem(T item) {
        items.put(item.getUniqueId(), item);
    }
    
    public T findById(String id) {
        return items.get(id);
    }
    
    public List<T> findAvailableItems() {
        List<T> availableItems = new ArrayList<>();
        
        for (T item : items.values()) {
            if (item.isAvailable()) {
                availableItems.add(item);
            }
        }
        
        return availableItems;
    }
    
    public int getCount() {
        return items.size();
    }
}

Step 5: Create the Library Class

package com.bloomtech.library;

import java.util.List;

public class Library {
    private final Catalog<Book> bookCatalog;
    private final Catalog<DVD> dvdCatalog;
    
    public Library() {
        this.bookCatalog = new Catalog<>();
        this.dvdCatalog = new Catalog<>();
    }
    
    public void addBook(Book book) {
        bookCatalog.addItem(book);
    }
    
    public void addDVD(DVD dvd) {
        dvdCatalog.addItem(dvd);
    }
    
    public Book findBookById(String id) {
        return bookCatalog.findById(id);
    }
    
    public DVD findDVDById(String id) {
        return dvdCatalog.findById(id);
    }
    
    public List<Book> findAvailableBooks() {
        return bookCatalog.findAvailableItems();
    }
    
    public List<DVD> findAvailableDVDs() {
        return dvdCatalog.findAvailableItems();
    }
    
    public void checkOutItem(LibraryItem item) {
        item.checkOut();
    }
    
    public void returnItem(LibraryItem item) {
        item.checkIn();
    }
    
    public int getTotalItemCount() {
        return bookCatalog.getCount() + dvdCatalog.getCount();
    }
}

Step 6: Creating a Demo Application

package com.bloomtech.library;

public class LibraryDemo {
    public static void main(String[] args) {
        // Create a library
        Library library = new Library();
        
        // Add some books
        Book book1 = new Book("B001", "Effective Java", "Joshua Bloch", "978-0134685991", 416);
        Book book2 = new Book("B002", "Clean Code", "Robert C. Martin", "978-0132350884", 464);
        
        // Add some DVDs
        DVD dvd1 = new DVD("D001", "The Matrix", "Wachowski Sisters", 136);
        DVD dvd2 = new DVD("D002", "Inception", "Christopher Nolan", 148);
        
        // Add items to library
        library.addBook(book1);
        library.addBook(book2);
        library.addDVD(dvd1);
        library.addDVD(dvd2);
        
        // Display total items
        System.out.println("Total items in library: " + library.getTotalItemCount());
        
        // Check out an item
        System.out.println("\\nChecking out " + book1.getTitle());
        library.checkOutItem(book1);
        
        // Find available books
        System.out.println("\\nAvailable books:");
        for (Book book : library.findAvailableBooks()) {
            System.out.println(" - " + book.getTitle() + " by " + book.getAuthor());
        }
        
        // Try to find an item by ID
        String searchId = "D001";
        DVD foundDVD = library.findDVDById(searchId);
        if (foundDVD != null) {
            System.out.println("\\nFound DVD: " + foundDVD.getTitle() + " directed by " + foundDVD.getDirector());
            System.out.println("Runtime: " + foundDVD.getRuntime() + " minutes");
        }
        
        // Return an item
        System.out.println("\\nReturning " + book1.getTitle());
        library.returnItem(book1);
        
        // Check available books again
        System.out.println("\\nAvailable books after return:");
        for (Book book : library.findAvailableBooks()) {
            System.out.println(" - " + book.getTitle() + " by " + book.getAuthor());
        }
    }
}

Practice: Extend the System

Try extending the library system with:

  • A Magazine class extending Item
  • A Borrower class to represent library users
  • Functionality to track which borrower has checked out which items