Overview
This portfolio aims to highlight my contributions to our team project, 'LiBerry'.
'LiBerry' is a library management system that is designed for small communities with a lack of expertise and resources to manage a library.
This library management system is able to manage books in the library, register borrowers, loan and return books, as well as calculate loan periods and fines for any overdue loans.
I was in charge of implementing the Generate loan slip feature and the Book feature. Additionally, I am responsible for the code quality and testability of the team’s code base throughout the entire development phase.
In this portfolio, I will illustrate my contributions in documenting the user guide and developer guide. These documentations serve to aid librarians and developers in understanding the features of the software.
Legend
I have used symbols to give a visual explanation to certain parts of this portfolio. This section aims to explain the meaning behind the usage of these symbols.
Denotes useful tips. |
Denotes additional information. |
Summary of contributions
This section shows a summary of my contributions to the team project and will include the main enhancement (Generating Loan Slip), code contribution and other contributions.
Major enhancement - Generate Loan Slip feature
This feature allows librarians to automatically generate loan slips in Portable Document Format (PDF) for every loan. I will explain in detail below what the feature is about and why it is an important feature.
What the feature does
This feature generates loan slips so that the librarian can immediately print the loan slip for the borrower. The printed loan slip contains all information about the loan or renew, including a list of loaned books and the due date of these loans.
Justification
Since our target group is small impoverished communities, it is unlikely they will have reliable internet access to check the status of their loans. Therefore, it will be suitable for librarians to provide them with a printed version of the loan.
Highlights
This feature is challenging to implement as it will require us to create a new PDF document from scratch. It was required of me to understand a great deal about file input and output in Java, which was something out of the scope of the course. Additionally, this document would have to be suitably styled to display a certain level of professionalism.
Why this is a major feature
This feature represents most of the core features of 'LiBerry' in a condensed PDF. I have provided a breakdown below as to how this feature achieves the required depth, completeness and level of effort.
-
Depth: This feature is deeply linked with the Book, Loan and Borrower features as it has to display information relevant to these features.
-
Completeness: This feature is complete with the intended style has been rigorously tested in many test cases.
-
Effort: This feature required an in-depth understanding of handling external libraries as well as file input and output. These information are not taught in the course and therefore required extensive research on my part.
Credits
This feature is made possible with the 'iText 7' library. However, it was still required of me to understand both the
Java File
class and the API well such that I can use it appropriately in the context of our project.
Other contributions:
Project management:
-
Managed the release of
v1.3
on GitHub. -
Continually added test cases throughout development phase to ensure consistent code quality. Done through the following Pull Requests:
Enhancements to existing features:
These enhancements are done through the following Pull Requests:
Documentation:
The documentations are updated through the following Pull Requests:
Contributions to the User Guide
This section outlines my contributions to the team’s User Guide. It demonstrates my ability to write documentation for librarians to understand how to use the software. Please refer to the User Guide for the full documentation.
Book feature
Adding a book: add
Adds a new book to library records.
Format: add t/TITLE a/AUTHOR [sn/BOOK_SN] [g/GENRE]…
A book can have up to 5 genres (but can have no genres as well). |
You do not need to specify the serial number if you wish so. LiBerry will then auto-generate a valid serial number for the new book. |
Examples:
-
add t/Harry Botter a/Raylei Jolking sn/B02010 g/children
Adds a children book titled "Harry Botter" by "Raylei Jolking", with the serial number "B02010", to LiBerry. -
add t/Inferno a/Tande g/classic g/epic
Adds a book titled "Inferno" by "Tande", with the genres "classic" and "epic" to LiBerry. The serial number for this book will be automatically generated.
Deleting a book : delete
Deletes a book from the library records. Used when book is lost or trashed.
Format: delete INDEX
or delete sn/BOOK_SN
Examples:
-
find t/harry
delete 1
Deletes the 1st book in the results of thefind
command. -
delete sn/B00422
Deletes the book with serial numbersn/B00422
.
Generating a loan slip
Exiting Serve Mode: done
Exits Serve Mode.
Format: done
After loaning all books, upon the done
command, a printable loan slip in pdf format will be generated.
The loan slip will be opened in your computer’s pdf viewer and also saved in the loan_slips
folder.
The figure below shows an example of how a loan slip might look like.
In the figure above, we can see that the loan slip records all the books borrowed by 'Bill'.
Contributions to the Developer Guide
This section highlights my contributions to the Developer Guide. It demonstrate my ability to aid other developers in understanding the various implementations of the features. Please refer to the Developer Guide for the full documentation.
Implementation of Book feature
Details of Implementation
The add book function is facilitated by Catalog
.
The Catalog
stores a list of books, representing the books in the library.
Additionally, it implements the following operation:
-
Catalog#addBook(book)
— Add a new book to the list of books in the catalog.
Given below is an activity diagram of a book being added to the catalog.
The else branch of each branch node should have a guard condition [else] but due to a limitation of PlantUML,
they are not shown.
|
We can clearly see how the system decides to generate a valid serial number base on whether the user input contains a valid serial number or not.
After the book is added to the system, we can now represent it with a class diagram shown below.
Book
Notice how the book can hold either 1 or 0 loans, depending on whether it is currently loaned out or not.
The current state of this newly-added book is further illustrated by the object diagram below.
Book
We can see that the book holds an Optional<Loan>
and has an empty LoanHistory
,
making it consistent with the class diagram of Book
above.
Design Considerations
Aspect: Data structure to store books.
-
Alternative 1 : Store them only in a ObservableList as per the original AddressBook implementation.
-
Pros: Will be easy to implement.
-
Cons: Iterating through the list of books to retrieve one may be inefficient.
-
-
Alternative 2 (current choice): Store them in a HashMap.
-
Pros: Will be easier (and more readable ) to retrieve books by serial number.
-
Cons: Will incur additional memory to maintain the HashMap.
-
We have decided to go with Alternative 2. There is a lot of retrieval of book objects within the Book and Loan features. Therefore, the benefits of quick retrieval of book will outweigh the additional memory costs incurred to maintain the HashMap.
Aspect: Generating a unique serial number.
Since we allow librarians to provide their own valid serial number when adding a book, we cannot use the number of books or the largest serial number to generate the next serial number.
-
Alternative 1: Use a TreeMap to store current serial numbers.
-
Pros: Will be efficient in generating the next valid serial number.
-
Cons: Will incur additional memory to maintain the TreeMap. Might also result in unexpected behaviour in some edge cases.
-
-
Alternative 2 (Current choice): Iterate from the beginning to obtain the first unused serial number.
-
Pros: Will be easy to implement.
-
Cons: Will be inefficient once the number of books grow.
-
We have decided to go with Alternative 2 and keep it simple. This is because there are some cases which leads to unexpected behaviour from Alternative 1. Furthermore, Alternative 2 is in line with the KISS (Keep it Simple, Stupid) principle of programming.
Implementation of Generate Loan Slip feature
Details of Implementation
The printing of loan slip feature is facilitated by LoanSlipUtil
.
Essentially, LoanSlipUtil
implements the following operations:
-
LoanSlipUtil#mountLoan()
— Mounts a loan in the current loan session. -
LoanSlipUtil#clearSession()
— Clears the loan session by unmounting all loans. -
LoanSlipUtil#createLoanSlipInDirectory()
— Creates a pdf version of the mounted loans as a single loan slip, saved in the loan_slips folder.
Given below is the sequence diagram of the generation of loan slip during the loan of a book.
The sequence diagram above is described by the following sequence of events:
Design Considerations
Aspect: How to create and use an instance of a LoanSlipDocument
.
-
Alternative 1 : Use the
LoanSlipDocument
constructor directly.-
Pros: Will be straightforward to implement.
-
Cons: The
Logic
component and theLoanCommand
object needs to know all the methods ofLoanSlipDocument
to be able to create a loan slip.
-
-
Alternative 2 (current choice): Create a Facade class
LoanSlipUtil
to facilitate creation ofLoanSlipDocument
.-
Pros: The
Logic
component and theLoanCommand
object can now use the full functionality ofLoanSlipDocument
via the static classLoanSlipUtil
without knowing the internal implementation ofLoanSlipDocument
. -
Cons: There is more code to be written and maintained.
-
We have decided to go with Alternative 2 as it decouples the code, making it easier to modify in the future. On the contrary, Alternative 1 will introduce unnecessary dependencies between classes, thereby increasing coupling and reducing maintainability.
Aspect: Implementation to allow extension (loan multiple books at one go).
-
Alternative 1 (current choice): Mount a loan in
LoanSlipUtil
for each book.-
Pros: Will be able to mount multiple loans using
LoanSlipUtil
before generating all loans in a single loan slip. -
Cons: Will require more code when mounting loans in the Facade class.
-
-
Alternative 2: Re-create
LoanSlipDocument
whenever a new loan comes in.-
Pros: Will only need to make adjustments to
Logic
component to contain anOptional<LoanSlipDocument>
field and update when a newLoan
comes in. -
Cons: Violates Single Responsibility Principle as the Logic class will now have to change if we change the implementation of
LoanSlipDocument
.
-
We have decided to go with Alternative 1 as it allows us to have flexible code that is easily extendable. Furthermore, it adheres to good programming practices as compared to Alternative 2, which violates the Single Responsibility Principle.