Overview
MediBook is an alternative to the primitive pen and paper management system for hospitals to store patient data as well as doctor information and their schedule. It allows doctors to have essential patients information at their fingertips. In accordance with PDPA, doctors will only be able to see patients information that are relevant to them. The user interacts with it using a CLI with a basic GUI. It is written in Java, and has about 5 kLoC
Summary of contributions
-
Major enhancement: added the ability to undo/redo previous commands
-
What it does: allows the user to undo changes that are made by mistake. This can be reversed by using the redo command.
-
Justification: This feature improves the product significantly because it allows the user to rectify their mistakes.
-
Highlights: This enhancement requires an in-depth understanding of how each existing command works as well as commands that will be added in the future. This makes the implementation challenging as modifications have to be made on existing commands and any new commands that will be added in.
-
-
Major enhancement: added the ability to associate a patient with a doctor and vice versa
-
What it does: allows the user to associate two person of different title (patient or doctor) in the MediBook. Once associated, the user can list all the people associate to a person.
-
Justification: This feature improves the product significantly because it allows the user to create connections between a patient and a doctor and thus, allows the staff to know the doctors whom are in charge of a particular patient and the patients whom a particular doctor is in charge of.
-
-
Minor enhancement:
-
Added a history command that allows the user to view a list of commands that were executed previously.
-
Added a “Title” field in the Person class to differentiate a patient and a doctor in MediBook
-
-
Code contributed: [Code]
-
Other contributions:
Contributions to the User Guide
Given below are sections I contributed to the User Guide. |
4.11 Associate a patient and a doctor: link
Create an association between person specified at INDEX1 and the person specified at INDEX2
Format: link INDEX1 INDEX2
Similar to viewall, view and delete, it requires list or find command to be called at least once in the session for an index reference to edit-appointment. |
Examples:
-
list
link 1 2
Associate the 1st person with the 2nd person in MediBook.
4.12 Remove association : unlink
Removes association between person specified at INDEX1 and the person specified at INDEX2
Format: link INDEX1 INDEX2
Similar to viewall, view and delete, it requires list or find command to be called at least once in the session for an index reference to edit-appointment. |
Examples:
-
list
unlink 1 2
Removes association between the 1st person with the 2nd person in MediBook.
4.13 Listing all persons associated: associatelist
Shows a list of persons associated with the specified person
Format: associatelist INDEX
Similar to viewall, view and delete, it requires list or find command to be called at least once in the session for an index reference to edit-appointment. |
Examples:
-
list
associatelist 2
Views the persons associated with the 2nd person in MediBook.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. |
3.3 Logic Component
Class diagram for the Logic Component:
Sequence diagram when a command is called (in this example, "delete 1") :
4.1 State control (undo/redo)
The state control feature allows the user to manipulate the different states of the MediBook in the current session with the undo and redo command. This section will describe the implementation of this feature.
4.1.1 Current implementation
The state control mechanism is managed by the CommandStack class. It supports the undo-ing and redo-ing of commands that modifies the contents of the MediBook in the current session.
These commands will extend from UndoAbleCommand
instead of Command
. These commands are then managed by the undoStack and the redoStack.
The following diagram shows the inheritance diagram for commands:
Commands that inherits from Command
are implemented this way:
public class FindCommand extends Command {
@Override
public CommandResult execute() {
//Find Logic
}
//...more code...
}
On the other hand, commands that inherit from UndoAbleCommand are implemented this way:
public class ClearCommand extends UndoAbleCommand {
@Override
public CommandResult execute() {
//Clear Logic
}
@Override
public void executeUndo() {
//Logic to undo clear
}
@Override
public void executeRedo() {
//Logic to redo clear
}
//...more code...
}
As shown, the commands that extends from the UndoAbleCommand will need to know how to undo and redo the changes they have made. This requires the object to store information of the change made. For example the DeleteCommand object will need store the person that was deleted so that the change made can be undone.
Below is an example usage scenario and the behaviours of the component at a given time:
1. On start-up:
CommandStack will be initialised with an empty undoStack
and redoStack
.
2. User executes a command that make changes to the MediBook (e.g add John Doe…):
The add
command will do a`commandStack.checkForAction()` and subsequently addCommandToStack()
which adds the AddCommand object into the undoStack
.
commandStack.checkForAction() will only be called if the command has been executed successfully. If it fails its execution, the object will not be pushed into the undoStack .
|
3. User executes another command that make changes to the MediBook (e.g delete 1):
The same procedures as step 2 applies and the new DeleteCommand
will be pushed into the undoStack
on top of the previous AddCommand
object.
4. User wants to undo the change they just made and executes the undo
command:
The undo command calls commandHistory.undoLast()
which will get the object at the top of the undoStack
, call its executeUndo()
method, push it into the redoStack
and then remove it from the undoStack.
If the user execute undo command when the undoStack is empty, the undoLast() method will throw a HistoryOutOfBoundException() which will be caught in the UndoCommand class and will display an error to the user instead.
|
5. User executes another command that make changes to the MediBook after the undo (e.g clear):
The clear
command calls commandStack.checkForAction()
which determines that this command was made following an undo
command and therefore requires truncateOldPath()
to be called. In this case, the redoStack
will be cleared before the ClearCommand object is pushed into the undoStack
.
The following sequence diagram shows how the undo operation works after the command is parsed:
4.1.1 Current implementation
Current implementation requires each UndoAbleCommand object to know how to revert their own changes.This will use less memory as minimal data is stored. For example, for add
, only the person added will be saved. However, we must ensure that the implementation of each individual command are correct.
4.1.3 Alternative consideration
An alternative to the current implementation is to save the different states of the MediBook after each command and iterate through them whenever undo/redo is called. Though this is far less challenging than the current implementation, performance issues might arise due to the high memory usage required.
4.5 Association
The association feature allows users to associate a doctor together with a patient via the link and unlink command, as well as view the persons who are associated via the associatelist command. This segment will elaborate on the implementation of this feature.
4.5.1 Current Implementation
The association feature is implemented as a Set of Associated
objects. The associated object will hold a String which contains the name and nric of the person that is associated.
4.5.2 Reason for Implementation
This implementation is basically storing a String of an associated person’s name and their nric into a set, which is simple to implement. However, since this implementation only stores a set of string, theres is nothing much you can do with it other than viewing it.
4.5.3 Alternative Implementation
An alternative implementation is to store the associated person object instead of just a String of their name and nric. This allows us to directly interact with the list generated by associatelist
like how the we interact with list
and find
. However, this requires saving/loading the persn object to/from a String since the data is stored in addressbook.txt, which can be rather challenging.