PROJECT: MediBook


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:

    • Project management:

      • Managed releases v1.1 - v1.4 (4 releases) on GitHub

    • Documentation:

      • Did some tweaks to organise contents of the Readme: #12 , #17 , #167

Contributions to the User Guide

Given below are sections I contributed to the User Guide.

Create an association between person specified at INDEX1 and the person specified at INDEX2
Format: link INDEX1 INDEX2

Links the person at the specified INDEX1 with the person at the specified INDEX2. One of them must be a doctor and the other one must be a patient The index refers to the index number shown in the most recent listing.

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.

Removes association between person specified at INDEX1 and the person specified at INDEX2
Format: link INDEX1 INDEX2

The index refers to the index number shown in the most recent listing. If there are no association between the two, user will see an message stating that instead.

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

Show the people associate with the person at the specified INDEX. The index refers to the index number shown in the most recent listing.

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:

LogicComponentClassDiagram

Sequence diagram when a command is called (in this example, "delete 1") :

LogicComponentSequence1

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:

UndoAbleCommand

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.

statecontrolimple1

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.

statecontrolimple2
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.

statecontrolimple3

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.

statecontrolimple4
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.

statecontrolimple5

The following sequence diagram shows how the undo operation works after the command is parsed:

UndoRedoSequenceDiagram

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.