Intermediate 25 min read

Review and Refactor

By the end of this lesson, you'll be able to:

  • Identify duplicated record-fetching logic across LibraryService methods
  • Extract a private helper method to remove that duplication
  • Confirm the refactor preserves every method's existing behavior

Prerequisites: "Handle Errors"

Spotting the duplication

public Checkout__c checkOutBook(Id bookId, String memberName) {
    Book__c book = [SELECT Id, Is_Checked_Out__c FROM Book__c WHERE Id = :bookId];
    // ...
}

public List<Book__c> getBookDetails(Id bookId) {
    Book__c book = [SELECT Id, Title__c, Author__c, Is_Checked_Out__c FROM Book__c WHERE Id = :bookId];
    // ...
}

Both methods query Book__c by Id individually — slightly different field lists, but the same underlying "fetch this one book" shape repeated across the class.

Extracting a shared private helper

private Book__c getBookById(Id bookId) {
    return [SELECT Id, Title__c, Author__c, Is_Checked_Out__c FROM Book__c WHERE Id = :bookId];
}

public Checkout__c checkOutBook(Id bookId, String memberName) {
    Book__c book = getBookById(bookId);
    if (book.Is_Checked_Out__c) {
        throw new LibraryException('This book is already checked out.');
    }
    book.Is_Checked_Out__c = true;
    update book;

    Checkout__c checkout = new Checkout__c(Book__c = bookId, Member_Name__c = memberName, Checkout_Date__c = Date.today());
    insert checkout;
    return checkout;
}

getBookById is private — an internal implementation detail, exactly like the helper methods extracted in Modules 12 and 17. Selecting a slightly wider field list once (covering every field any method needs) means every caller gets a consistent, complete Book__c without repeating the query's field list everywhere.

Confirming behavior hasn't changed

LibraryService library = new LibraryService();

Checkout__c checkout = library.checkOutBook(someBookId, 'Amara Nkosi'); // still works exactly as before

Every existing caller of checkOutBook, returnBook, and the rest still behaves identically — this refactor only changed how the class fetches a Book__c internally, not what any of its public methods promise to callers. This is the whole point of refactoring, revisited one final time to close out this project.

Exercise

Refactor returnBook to use the new getBookById helper instead of writing its own query for the related Book__c.

Show hint

Replace the inline query with a call to getBookById(checkout.Book__c).

APEX

Review and Refactor Quiz

1. After extracting getBookById as a shared private helper, what should be true about checkOutBook's public behavior?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

The final lesson reviews LibraryService as a whole, extracting a repeated "fetch the book and check it exists" pattern into a shared private method — the same refactoring discipline from Modules 12 and 17.