About the Project
My team and I were tasked with enhancing a application addressbook-level4 for our Software Engineering project. We chose to morph it into an book review recording application called BookSquirrel. This enhanced application enables readers to keep track of their reading, recording down their reviews of books and obtain statistics of their past reading habits.
My role was to design and write the codes to support the CRUD of books. The following sections illustrate these enhancements in more detail, as well as the relevant sections I have added to the user and developer guides in relation to these enhancements.
Summary of contributions
This section shows a summary of my coding, documentation, and other helpful contributions to the team project.
-
Major enhancement: Support CRUD of book object.
-
What it does: Allows the user to add, edit, delete book in the book shelf and check reviews of selected book
-
Justification: This feature is the basis of the application. As our app is viewed as a big book shelf that keeps numerous books and the reviews related to each book. The CRUD features of book object is necessary to support all the other operations.
-
Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands.
-
-
Minor enhancement: Modified the UI to make it better suit our product
-
Code contributed: [Link to Code]
-
Other contributions:
-
Project management:
-
Managed releases
v1.1
-v1.4
(4 releases) on GitHub -
Setting up Travis, Coveralls, Codacy for code checking purpose.
-
Managing Issue Tracker and merging of PRs.
-
-
Enhancements to existing features:
-
Documentation:
-
Community:
-
Contributions to the User Guide
We had to update the original addressbook User Guide with instructions for the enhancements that we had added. The following is an excerpt from our BookSquirrel User Guide, showing additions that I have made for the CRUD features for book.
Features
Command Format
-
The total length of user input should not exceed 500 characters (space included).
-
Words in
UPPER_CASE
are the parameters to be supplied by the user e.g. inaddBook n/NAME
,NAME
is a parameter which can be used asaddBook n/Book
. -
Words in
UPPER_CASE
without brackets are the parameters that should only be supplied once e.g. inaddBook n/NAME
,NAME
is a parameter which should only appear once in user input,addBook n/John Doe n/Alice
is not allowed. -
Items in square brackets are optional (can be supplied once or not at all) e.g
n/NAME [a/AUTHOR]
can be used asn/Alice in Wonderland a/Jack
or asn/Alice in Wonderland
. -
Items with
…
after them can be used multiple times including zero times e.g.[t/TAG]…
can be used ast/fantasy
,t/fantasy t/textbook
etc. -
Parameters can be in any order e.g. if the command specifies
n/NAME a/AUTHOR
,a/AUTHOR n/NAME
is also acceptable. -
Book name, review title and review content should only contain alphanumeric characters, space,
*
,,
,.
,?
,'
,(
,)
and&
. -
Author and tag should only contain alphanumeric characters and spaces.
-
The Book name and author should not exceed 50 characters (space included).
-
Review title should not exceed 50 characters (space included).
-
Review content should not exceed 400 characters (space included).
-
Rating should be an integer from 0 to 10 inclusive and the input should be 1 or 2 digit number.
-
Tags should not exceed 20 characters (space included).
Book Commands
Adding a book: addBook
Adds a book to the Bookshelf
Format: addBook n/BOOKNAME a/author m/RATING [t/TAG]…
Examples:
-
addBook n/Alice in Wonderland a/Lewis Carroll m/5 t/fantasy t/fairy tale
Adds a book named Alice in Wonderland to the record. The book is written by Lewis Carroll, rated 5 stars, and labeled with tags ‘fantasy’ and ‘fairy tale’.
Figure 1. Result display after successful execution of addBook n/Alice in Wonderland a/Lewis Carroll m/5 t/fantasy t/fairy tale
.
Editing book entry : editBook
Edits an existing book entry (eg. edit the book name, rating, author or tag).
Format: editBook INDEX [n/BOOKNAME] [a/AUTHOR] [m/RATING] [t/TAG]…
Examples:
-
editBook 1 n/Alice in Wonderland a/some author t/some tag
Change the name, author, tag of the first book to Alice in Wonderland, some author, some tag.
Figure 2.1 Result display before the the execution of editBook 1 n/Alice in Wonderland a/some author t/some tag
.
Figure 2.2 Result display after the the execution of editBook 1 n/Alice in Wonderland a/some author t/some tag
.
-
editBook 2 t/
Clear all the existing tags of the second book in the result list.
Contributions to the Developer Guide
The following section shows my additions to the BookSquirrel Developer Guide for the addBook features.
AddBook feature
Current Implementation
The addBook mechanism is facilitated by BookShelf
.
It contains UniqueBookList
in which all the book data are stored and duplicates are not allowed. Books with same book name are considered as duplicates.
Additionally, it uses the following operations from BookShelf
:
-
model#hasBook()
— Check if the book already exists in the Bookshelf. -
model#addBook()
— To add the new book into Bookshelf. -
model#commitBookShelf()
— Saves the current Bookshelf state for undo/redo..
These operations are exposed to the Model
interface.
Given below is an example usage scenario and how the addBook mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedBookShelf
will be initialized with the initial bookshelf state, and the currentStatePointer
pointing to that single bookshelf state.
Step 2. The user executes addBook n/Alice a/HR m/5 tag/fantasy
command to add the book called Alice, written by HR, with a rating of 5 and tag of fantasy in the Bookshelf. The AddBookCommandParser
check if the command is in valid format.
If the command is not in valid format, ParseException(MESSAGE_INVALID_COMMAND_FORMAT) will be thrown. The book will not be added to the bookshelf. |
Step 3. The addBook
command calls Model#hasBook()
, checking if the book already exists in the bookshelf.
If the book already exists, CommandException(MESSAGE_DUPLICATE_BOOK) will be thrown. It will not call Model#commitBookShelf() , so the bookshelf state will not be saved into the BookShelfStateList .
|
Step 4. The bookshelf now adds the book to the Bookshelf after making sure there are no duplicates, and calls Model#commitBookShelf(), causing the modified state of the Bookshelf after the addBook
command executes to be saved in the BookShelfStateList
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command addBook n/Alice a/HR m/5 tag/fantasy
.
The following activity diagram summarizes what happens when a user executes an AddBook command:
Design Considerations
Aspect: How duplicate of book is defined
-
Alternative 1 (current choice): Books with same book name are considered as duplicates.
-
Pros: Easy to support other commands such as addReview which search for the book based on its name.
-
Cons: User may encounter trouble if they read two books with the same name but written by different authors.
-
-
Alternative 2: Books with multiple identical fields (eg. book name and author, book name and rating, etc) are considered as the same book.
-
Pros: Able to store books with same but different in other fields.
-
Cons: Causing trouble in executing other commands like addReview as more parameters must be provided to search for a certain book.
-
Aspect: Data structure to support the addBook command
-
Alternative 1 (current choice): Saves the entire book as one object contains different fields such as author, rating, etc.
-
Pros: Easy to implement delete and other features that change an entire book.
-
Cons: Maybe more difficult to implement the summary feature which needs to obtain statistics of all separate fields stored in each book, eg. find the most popular author.
-
An example of the current model is given below. |
-
Alternative 2: Store a Tag list and an Author List in BookShelf, which Book can reference.
-
Pros: Easier to obtain statistics regarding each component.
-
Cons: It is harder to manage book object as we need to find a way to connect all components together.
-
An example of the alternative model is given below. |
EditBook feature
Current Implementation
The editBook mechanism is facilitated by BookShelf
.
It contains UniqueBookList
in which all the book data are stored and duplicates are not allowed. Books with same book name are considered as duplicates.
Additionally, it uses the following operations from BookShelf
:
-
model#hasBook()
— Check if the book already exists in the Bookshelf. -
model#setBook()
— To set a book with field values provided. -
model#commitBookShelf()
— Saves the current Bookshelf state for undo/redo..
These operations are exposed to the Model
interface.
Given below is an example usage scenario and how the addBook mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedBookShelf
will be initialized with the initial bookshelf state, and the currentStatePointer
pointing to that single bookshelf state.
Step 2. The user executes editBook 1 n/Alice a/HR m/5 tag/fantasy
command to edit the first book present in the Bookshelf to be a book called Alice, written by HR, with a rating of 5 and tag of fantasy in the Bookshelf. The addBook
command calls Model#hasBook()
, checking if the book already exists in the bookshelf.
If the new book name already exists, CommandException(MESSAGE_DUPLICATE_BOOK) will be thrown. It will not call Model#commitBookShelf() , so the bookshelf state will not be saved into the BookShelfStateList .
|
Step 4. The bookshelf now set the fields of the first book to the new ones provided, and calls Model#commitBookShelf(), causing the modified state of the Bookshelf after the addBook
command executes to be saved in the BookShelfStateList
Design Considerations
Aspect: How editBook is executed
-
Alternative 1 (current choice): Use the index to figure out the book user wishes to edit.
-
Pros: Easy to select the book user wish to edit with the support of our UI.
-
Cons: A listBook command might be needed before executing editBook if the current filtered Bookshelf is empty
-
-
Alternative 2: Use exact book name to figure out the book user wishes to edit.
-
Pros: No need to first filter out a non-empty Bookshelf.
-
Cons: Causing trouble for the user to type in the full name of the book.
-