Skip to content

Commit 3b05b81

Browse files
authored
feat: adds Lesson 10 homework assignment and stretch requirement. (#284)
* feat: adds library implementation and tests * chore: updated doco comment. * docs: adds additional assignment details * chore: updates section title.
1 parent 22bbc6f commit 3b05b81

File tree

10 files changed

+710
-2
lines changed

10 files changed

+710
-2
lines changed

lesson_10/README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818
* Read HFDP 1-2.
1919
* Complete [Applying SOLID principles](#applying-solid-principles) exercise.
2020

21-
## Applying SOLID Principles
21+
## Applying SOLID Principles (Library Management System, Part II)
2222

23-
* TODO(anthonydmays): Add details
23+
In this assignment, you will be given starting implementations for the `Library`, `Book`, and `Patron` classes. You will need to add the following enhancements to support new functionality:
24+
25+
* We now want to support the concept of a `Librarian`. A librarian should be able to check out or check in books just like other patrons. Books can no longer be added or removed from the `Library` without a librarian.
26+
* We also want to support other types of media formats, including `Dvd`, `Magazine`, and `Newspaper` types. Patrons cannot check out `Magazine` or `Newspaper` items.
27+
* [Stretch] Add the ability to search for items in the library by title, ISBN, author, or type. Extra credit will not be assigned unless the previous requirements have been met.
28+
29+
You will need to make changes to code in the [solid/][solid-folder] sub-folder and submit your PR for credit. Don't forget to follow the Conventional Commit spec for your commit messages and pull requests title and descriptions.
30+
31+
[solid-folder]: ./solid/
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.codedifferently.lesson10.library;
2+
3+
import com.codedifferently.lesson10.library.exceptions.LibraryNotSetException;
4+
import com.codedifferently.lesson10.library.exceptions.WrongLibraryException;
5+
import java.util.List;
6+
import java.util.Objects;
7+
8+
/** Represents a book. */
9+
public class Book {
10+
private Library library;
11+
private String title;
12+
private String isbn;
13+
private List<String> authors;
14+
private int numberOfPages;
15+
16+
/**
17+
* Create a new book with the given title, ISBN, authors, and number of pages.
18+
*
19+
* @param title The title of the book.
20+
* @param isbn The ISBN of the book.
21+
* @param authors The authors of the book.
22+
* @param numberOfPages The number of pages in the book.
23+
*/
24+
public Book(String title, String isbn, List<String> authors, int numberOfPages) {
25+
this.title = title;
26+
this.isbn = isbn;
27+
this.authors = authors;
28+
this.numberOfPages = numberOfPages;
29+
}
30+
31+
/**
32+
* Get the id of the book.
33+
*
34+
* @return The id of the book.
35+
*/
36+
public String getId() {
37+
return this.isbn;
38+
}
39+
40+
/**
41+
* Get the library that the book is in.
42+
*
43+
* @param library The library that the book is in.
44+
* @throws WrongLibraryException If the book is not in the library.
45+
*/
46+
public void setLibrary(Library library) throws WrongLibraryException {
47+
if (library != null && !library.hasBook(this)) {
48+
throw new WrongLibraryException(
49+
"Book " + this.getId() + " is not in library " + library.getId());
50+
}
51+
this.library = library;
52+
}
53+
54+
/** Get the title of the book. */
55+
public String getTitle() {
56+
return title;
57+
}
58+
59+
/** Get the ISBN of the book. */
60+
public String getIsbn() {
61+
return isbn;
62+
}
63+
64+
/** Get the authors of the book. */
65+
public List<String> getAuthors() {
66+
return authors;
67+
}
68+
69+
/** Get the number of pages in the book. */
70+
public int getNumberOfPages() {
71+
return numberOfPages;
72+
}
73+
74+
/**
75+
* Check if the book is checked out.
76+
*
77+
* @return True if the book is checked out, false otherwise.
78+
* @throws LibraryNotSetException If the library is not set for the book.
79+
*/
80+
public boolean isCheckedOut() throws LibraryNotSetException {
81+
if (this.library == null) {
82+
throw new LibraryNotSetException("Library not set for book " + this.getId());
83+
}
84+
return library.isCheckedOut(this);
85+
}
86+
87+
@Override
88+
public boolean equals(Object o) {
89+
if (this == o) return true;
90+
if (!(o instanceof Book)) return false;
91+
Book book = (Book) o;
92+
return Objects.equals(getIsbn(), book.getIsbn());
93+
}
94+
95+
@Override
96+
public int hashCode() {
97+
return Objects.hash(getId());
98+
}
99+
100+
@Override
101+
public String toString() {
102+
return "Book{" + "id='" + getId() + '\'' + ", title='" + getTitle() + '\'' + '}';
103+
}
104+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package com.codedifferently.lesson10.library;
2+
3+
import com.codedifferently.lesson10.library.exceptions.BookCheckedOutException;
4+
import java.util.HashMap;
5+
import java.util.HashSet;
6+
import java.util.Map;
7+
import java.util.Set;
8+
9+
/** Represents a library. */
10+
public class Library {
11+
private Set<String> bookIds = new HashSet<>();
12+
private Set<String> checkedOutIsbns = new HashSet<>();
13+
private Map<String, Set<Book>> checkedOutBooksByPatron = new HashMap<>();
14+
private Set<String> patronIds = new HashSet<>();
15+
private String id;
16+
17+
/**
18+
* Create a new library with the given id.
19+
*
20+
* @param id The id of the library.
21+
*/
22+
public Library(String id) {
23+
this.id = id;
24+
}
25+
26+
/**
27+
* Get the id of the library.
28+
*
29+
* @return The id of the library.
30+
*/
31+
public String getId() {
32+
return this.id;
33+
}
34+
35+
/**
36+
* Add a book to the library.
37+
*
38+
* @param book The book to add.
39+
*/
40+
public void addBook(Book book) {
41+
this.bookIds.add(book.getId());
42+
book.setLibrary(this);
43+
}
44+
45+
/**
46+
* Remove a book from the library.
47+
*
48+
* @param book The book to remove.
49+
*/
50+
public void removeBook(Book book) throws BookCheckedOutException {
51+
if (this.isCheckedOut(book)) {
52+
throw new BookCheckedOutException("Cannot remove checked out book.");
53+
}
54+
this.bookIds.remove(book.getId());
55+
book.setLibrary(null);
56+
}
57+
58+
/**
59+
* Add a patron to the library.
60+
*
61+
* @param patron The patron to add.
62+
*/
63+
public void addPatron(Patron patron) {
64+
this.patronIds.add(patron.getId());
65+
this.checkedOutBooksByPatron.put(patron.getId(), new HashSet<>());
66+
patron.setLibrary(this);
67+
}
68+
69+
/**
70+
* Remove a patron from the library.
71+
*
72+
* @param patron The patron to remove.
73+
*/
74+
public void removePatron(Patron patron) throws BookCheckedOutException {
75+
if (this.checkedOutBooksByPatron.get(patron.getId()).size() > 0) {
76+
throw new BookCheckedOutException("Cannot remove patron with checked out books.");
77+
}
78+
this.patronIds.remove(patron.getId());
79+
this.checkedOutBooksByPatron.remove(patron.getId());
80+
patron.setLibrary(null);
81+
}
82+
83+
/**
84+
* Check out a book to a patron.
85+
*
86+
* @param book The book to check out.
87+
* @param patron The patron to check out the book to.
88+
* @return True if the book was checked out, false otherwise.
89+
*/
90+
public boolean checkOutBook(Book book, Patron patron) {
91+
if (!this.canCheckOutBook(book, patron)) {
92+
return false;
93+
}
94+
this.checkedOutIsbns.add(book.getIsbn());
95+
this.checkedOutBooksByPatron.get(patron.getId()).add(book);
96+
return true;
97+
}
98+
99+
private boolean canCheckOutBook(Book book, Patron patron) {
100+
if (!this.hasBook(book)) {
101+
return false;
102+
}
103+
if (this.isCheckedOut(book)) {
104+
return false;
105+
}
106+
if (!this.hasPatron(patron)) {
107+
return false;
108+
}
109+
return true;
110+
}
111+
112+
/**
113+
* Check if the library has the given book.
114+
*
115+
* @param book The book to check for.
116+
* @return True if the library has the book, false otherwise.
117+
*/
118+
public boolean hasBook(Book book) {
119+
return this.bookIds.contains(book.getId());
120+
}
121+
122+
/**
123+
* Check if the given book is checked out.
124+
*
125+
* @param book The book to check.
126+
* @return True if the book is checked out, false otherwise.
127+
*/
128+
public boolean isCheckedOut(Book book) {
129+
return this.checkedOutIsbns.contains(book.getIsbn());
130+
}
131+
132+
/**
133+
* Check if the library has the given patron.
134+
*
135+
* @param patron The patron to check for.
136+
* @return True if the library has the patron, false otherwise.
137+
*/
138+
public boolean hasPatron(Patron patron) {
139+
return this.patronIds.contains(patron.getId());
140+
}
141+
142+
/**
143+
* Return a book to the library.
144+
*
145+
* @param book The book to return.
146+
* @param patron The patron returning the book.
147+
* @return True if the book was returned, false otherwise.
148+
*/
149+
public boolean checkInBook(Book book, Patron patron) {
150+
if (!this.hasBook(book)) {
151+
return false;
152+
}
153+
this.checkedOutIsbns.remove(book.getIsbn());
154+
this.checkedOutBooksByPatron.get(patron.getId()).remove(book);
155+
return true;
156+
}
157+
158+
/**
159+
* Get the books checked out by a patron.
160+
*
161+
* @param patron The patron to get the books for.
162+
* @return The books checked out by the patron.
163+
*/
164+
public Set<Book> getCheckedOutByPatron(Patron patron) {
165+
return this.checkedOutBooksByPatron.get(patron.getId());
166+
}
167+
168+
@Override
169+
public String toString() {
170+
return "Library{"
171+
+ "bookIds="
172+
+ bookIds
173+
+ ", checkedOutIsbns="
174+
+ checkedOutIsbns
175+
+ ", checkedOutBooksByPatron="
176+
+ checkedOutBooksByPatron
177+
+ ", patronIds="
178+
+ patronIds
179+
+ '}';
180+
}
181+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.codedifferently.lesson10.library;
2+
3+
import com.codedifferently.lesson10.library.exceptions.LibraryNotSetException;
4+
import com.codedifferently.lesson10.library.exceptions.WrongLibraryException;
5+
import java.util.Objects;
6+
import java.util.Set;
7+
8+
/** Represents a patron of a library. */
9+
public class Patron {
10+
private Library library;
11+
private String name;
12+
private String email;
13+
14+
/**
15+
* Create a new patron with the given name and email.
16+
*
17+
* @param name The name of the patron.
18+
* @param email The email of the patron.
19+
*/
20+
public Patron(String name, String email) {
21+
this.name = name;
22+
this.email = email;
23+
}
24+
25+
/**
26+
* Get the library that the patron is in.
27+
*
28+
* @param library The library that the patron is in.
29+
* @throws WrongLibraryException If the patron is not in the library.
30+
*/
31+
public void setLibrary(Library library) throws WrongLibraryException {
32+
if (library != null && !library.hasPatron(this)) {
33+
throw new WrongLibraryException(
34+
"Patron " + this.getId() + " is not in library " + library.getId());
35+
}
36+
this.library = library;
37+
}
38+
39+
/** Get the name of the patron. */
40+
public String getName() {
41+
return this.name;
42+
}
43+
44+
/** Get the email of the patron. */
45+
public String getId() {
46+
return this.email;
47+
}
48+
49+
/**
50+
* Gets the books currently checked out to the patron.
51+
*
52+
* @return The books currently checked out to the patron.
53+
* @throws LibraryNotSetException If the library is not set for the patron.
54+
*/
55+
public Set<Book> getCheckedOutBooks() throws LibraryNotSetException {
56+
if (this.library == null) {
57+
throw new LibraryNotSetException("Library not set for patron " + this.getId());
58+
}
59+
return this.library.getCheckedOutByPatron(this);
60+
}
61+
62+
@Override
63+
public boolean equals(Object o) {
64+
if (this == o) return true;
65+
if (!(o instanceof Patron)) return false;
66+
Patron patron = (Patron) o;
67+
return Objects.equals(getId(), patron.getId());
68+
}
69+
70+
@Override
71+
public int hashCode() {
72+
return Objects.hash(getId());
73+
}
74+
75+
@Override
76+
public String toString() {
77+
return "Patron{" + "id='" + getId() + '\'' + ", name='" + getName() + '\'' + '}';
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.codedifferently.lesson10.library.exceptions;
2+
3+
public class BookCheckedOutException extends RuntimeException {
4+
public BookCheckedOutException(String message) {
5+
super(message);
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.codedifferently.lesson10.library.exceptions;
2+
3+
public class LibraryNotSetException extends RuntimeException {
4+
public LibraryNotSetException(String message) {
5+
super(message);
6+
}
7+
}

0 commit comments

Comments
 (0)