Project: Health Hub

Greetings! I am a Year 2 undergraduate in NUS majoring in Computer Science with a passion for solving real world problems using my technical expertise in software development and technological knowledge. This portfolio details the contributions that I have made to HealthHub, the considerations and also the decisions made in my implementation of various functions in HealthHub.

Overview

In light of the overwhelming workload of hospital administration teams due to rising need for more and better healthcare services, we at team W09-2 have designed and developed a desktop application that aims to improve the hectic workload of hospital administrative staff by providing a simple and efficient solution for managing requests for healthcare services from home-stay patients: HealthHub.

HealthHub is a desktop application built in Java and JavaFX that supports both a Command Line Interface(CLI) and a Graphical User Interface(GUI), providing the user with the flexbility to choose the mode of use that he or she prefers.

As a member of the team tasked with the development of HealthHub, my role was to design the command logic structure for parsing commands and inputs entered by the user, as well as implementing the logic for commands involving HealthWorker which represents the details of medical experts register in HealthHub.

Notation

  • Words used that are highlighted in grey represents an existing Class or Object that is implemented in HealthHub. E.g HealthWorker denotes the object used to describe the details representing a registered medical expert.

Documentation under this section denotes any additional information used to supplement existing description.

Contributions

Summary of Contributions

Over the course of the development phase, I was tasked with the development of HealthWorker related features in HealthHub, such as the basic Create, Read, Update and Delete(CRUD) functionality. The enhancements and features that I have contributed to HealthHub are:

  • Creation of the HealthWorker representation model for describing a people working in the medical profession, in HealthHub.

  • add, edit and delete commands for registering HealthWorker into HealthHub.

  • Designing and implementing the architecture for CommandParser to provide flexibility for the development of other commands, as well as streamline the performance of user input parsing.

  • filter command for HealthWorker objects, utilizing a combination of optimized data structures and methods from Java’s Predicate and Function library.

Major Enhancements

  • I reworked the CommandParser classes in HealthHub to facilitate the parsing of inputs for commands involving both HealthWorker and Request objects.

    • The original implementation of CommandParser class in AddressBook4 only facilitated the adding of a Person class object into the system. As HealthHub stored multiple different types of objects such as HealthWorker and Request, I had to rework the existing implementation of CommandParser in AddressBook4 to cater to the needs of our application.

    • I created the CommandMode class for use in the new release for CommandParser class, and overhauled the implementation to use CommandMode to identify the specific type of object being handled, as well as to place restrictions on unvalidated user inputs during commands. My contribution to HealthHub via the CommandParser class paved the way for other teammates to use the new revised CommandParser class for the development of their features as well.

    • Adjusted the implementation for FilterCommandParser, ListCommandParser and DeleteCommandParser implemented by my teammates use CommandMode to for a more seamless integration of the filter, list and delete commands into HealthHub.

  • Added the functionality to filter HealthWorker objects in the HealthHub system using various fields.

    • In some of the user stories prior to the development of HealthHub, many potential users greatly favored the capability to be able to search for specific types of requests or medical workers, thus speeding up their search.

    • To facilitate the ease of finding and assigning HealthWorker in HealthHub, I implemented the ability to filter the existing list of HealthWorker. As a result, Users are able to reduce their search for the most appropriate health staff for assignment to requests to a shorter list based on filter conditions they input.

    • A significant difficulty that was faced when implementing this feature, is the ability to combine multiple conditions of user inputs. The two main solutions that were considered were firstly, storing all the filter conditions into a List<Predicate, while the second solution involved condensing all the filter conditions into a single Predicate using Java’s Predicate and Function library methods. The considerations for each solution are as follows:

Design Using a List of Predicate Composed Predicate using and method

How it works

Each user input condition will be parsed into Predicate, which are stored in an List. Pros: Easier to manage each single Predicate as they are kept separate Cons: Need to rework existing GUI implementation for filter as it only uses a single Predicate Object

Each user input will be parsed into a Predicate object, and all the Predicate formed will be composed into a single Predicate object. Pros: Ease of existing and future implementations as functionality only depends on Predicate Cons: Unable to specify actions for each Predicate

Implementation

User inputs are first parsed into Predicate equivalents, and then added to an ArrayList. FilterCommandParser then takes the existing UniqueHealthWorkerList, checks for HealthWorker whose fields matches the list of Predicate using allMatch method from the Predicate library, and then returns an ObservableList containing those HealthWorker.

User inputs are parsed into Predicate equivalents, which are then composed into a single Predicate containing the logic of all the composed Predicates using the and method from Predicate library. The composed Predicate is then set as the filter condition into the existing ObservableList of HealthWorker in the UI component.

  • Weighing both the pros and cons of both design considerations, I decided to go with composing multiple Predicates into a single Predicate by using the functional programming paradigm through Java’s Predicate and Function libraries. This is because doing so increases the ease of implementation for future enhancements to HealthHub with the increased flexibility, and also future implementations are less tightly coupled as they only need to depend on Predicate and not List.

 

Other Contributions

Minor Enhancements:

  • Added the ability for users to perform Create, Read, Update and Delete (CRUD) operations for health workers in HealthHub by implementing the add healthworker, edit healthworker and delete healthworker commands.

  • Wrote incremental integration tests for existing features in HealthHub, as well as features implemented by my teammates to ensure that the logic and model components in HealthHub are integrated together smoothly without hiccups.

Design:

  • Proposed the layout and structure of the implementation of the current Graphical User Interface(GUI) of HealthHub.

Project Management:

  • Proposed the architecture design of the current implementation for the command logic side of HealthHub.

  • Delegated features and roles to various team members for their contributions to HealthHub.

Documentation:

  • Contributed to the descriptions of each feature by reviewing the explanation of features in the User Guide, and overhauling it to be more informative and audience-focused.

  • Provided the notation and structure for my team to follow when documenting our changes and contributions made to HealthHub in the User Guide.

Community:

  • Reviewed PRs of fellow teammates, and gave suggestions on certain code snippets

  • Contributed to discussions on github pull requests by other team members, providing suggestions that were eventually adopted in our existing development releases.

Tools:

  • Set up the continuous integration plugins TravisCI for the team repository for HealthHub.

  • Set up auto-publishing of documentation for HealthHub for the team repository.

Contributions to the User Guide

As my team and I transformed the original implementation of AddressBook4 to HealthHub, we have also extensively updated the User Guide to allow for users to better understand what HealthHub aims to achieve, and how it does so.

The following sections details my contribution to the User Guide up til HealthHub version release v1.4.

Filtering health workers/requests: filter

When identifying health workers to assign to an open request, or to look for a particular patient details in certain requests, it may be useful to only display items in a list that match a particular constraint.

Using the filter command, you can set the GUI to display health workers and requests whose fields match the keywords`that are specified in the `filter command, allowing you to find the doctors who are experts in cardiology much quicker.

Format: filter <type> <keyword> [<more_keywords>]…​

Filter health workers:

Format:

  • filter healthworker <keyword> [<more_keywords>]

Shortcuts:

  • filter h <keyword> [<more_keywords>]

  • filter 1 <keyword> [<more_keywords>]

Upon entering the command with valid inputs, HealthHub searches the entire list of health workers in Health Hub, and only displays the health workers whose fields contains the parameters specified in the filter command as a substring.

  • Multiple conditions for filtering health workers can be added simultaneously for more expressive search. Note that if multiple parameters are specified, HealthHub displays healthworkers that match all the criteria mentioned.

  • To revert the view back to the original health worker list, enter the list healthworker command.

Examples:

  • filter h s/GENERAL_PRACTICE s/GYNAECOLOGY
    Returns all health workers whose field of expertise include general practice and gynaecology.

For specialisation fields, parameter values need not follow the exact format as the valid specialisation values provided under the add command section. Valid parameters may include case insensitive substrings (E.g 'physio' will match to 'PHYSIOTHERAPY'.

For example, to display only health workers who specialise in physiotherapy, the filter h s/physio command can entered, using the shortcut h for health worker mode and the substring physio instead for brevity, as shown in the image below, in the Before section:

filter healthworker UG

When the command is keyed into the application, HealthHub will display the state shown by the After section on the right side on the image above. The command terminal displays a message denoting how many health workers are found that has PHYSIOTHERAPY as a specialisation, and the health worker list on the right side of the GUI displays only health workers who has expertise in physiotherapy.

Contributions to the Developer Guide

To ensure that future developers contributing to HealthHub, as well as users who wish to improve the implementation and functionality of the application, my team and I have also published detailed documentation of each of the features we have implemented, so that potential contributors can easily understand the structure and logic of the features that we have put in place.

The following sections details my contribution to the Developer Guide for HealthHub up til version release v1.4:

Filtering HealthWorker

The filter command allows users to display only HealthWorker or Request whose fields matches the <parameter> specified in the filter command.

Format: filter healthworker/h/1 <prefix>/<parameter> [<prefix/<parameter>] …​

  • The filter command checks for HealthWorker whose field specific to the <specific> contains or matches the <parameter> provided.

  • Example: filter h n/John changes the UI to display only HealthWorker whose name is John, or contains John (Johnny, Johnson, …​)

Upon entering the filter command, the filter command word is stripped from the input and the argument fields are passed into the FilterCommandParser class. The regular expressions for checking the fields for name, organisation and skills follows the same format as mentioned in add command. If invalid parameters are specified by the user, or if an invalid keyword was specified that does not correspond to any CommandMode enum, then FilterCommandParser throws a ParseException and displays an error message to the user.

If valid inputs are provided, FilterCommandParser tokenizes the argument string without the keyword using ArgumentTokenizer object, mapping each parameter to it’s respective prefix in an ArgumentMultiMap object. FilterCommandParser then creates a Predicate object using the parameter values in ArgumentMultiMap for each filter condition, and composes them into a single Predicate using the and function in Predicate in conjuction with stream and reduce methods from Java’s Function library. The Predicate object composed is then passed into FilterHealthWorkerCommand, which sets the predicate for the HealthWorker list in the GUI to display only HealthWorker whose fields matches the Predicate set.

Design Considerations

During the implementation of the filter command, we decide between two alternative implementations of managing the Predicates created from multiple criteria input by the user.

The following table states the considerations for performance as well as future implementations and enhancements to HealthHub that were taken into account:

Design Using a List of Predicate Composed Predicate using and method

How it works

Each user input condition will be parsed into Predicate, which are stored in an List. Pros: Easier to manage each single Predicate as they are kept separate Cons: Need to rework existing GUI implementation for filter as it only uses a single Predicate Object

Each user input will be parsed into a Predicate object, and all the Predicate formed will be composed into a single Predicate object. Pros: Ease of existing and future implementations as functionality only depends on Predicate Cons: Unable to specify actions for each Predicate

Implementation

User inputs are first parsed into Predicate equivalents, and then added to an ArrayList. FilterCommandParser then takes the existing UniqueHealthWorkerList, checks for HealthWorker whose fields matches the list of Predicate using allMatch method from the Predicate library, and then returns an ObservableList containing those HealthWorker.

User inputs are parsed into Predicate equivalents, which are then composed into a single Predicate containing the logic of all the composed Predicates using the and method from Predicate library. The composed Predicate is then set as the filter condition into the existing ObservableList of HealthWorker in the UI component.

Ultimately, the decision was made to implement the filter command by composing the Predicate that were formed from the user inputs into a single Predicate using a combination of Java’s Function library methods stream and reduce, as well as the and method used in Java’s Predicate library.
This is because maintain a List of Predicate in HealthHub requires an unnecessary rework of many existing components in HealthHub in order to fit the new implementation of using a List, such as replacing Predicate in methods involved with List<Predicate>.

In addition, by returning a single Predicate object, ease of implementation of methods in filter command, as well as any future or existing enhancements to filter reduces the complexity of code as the function needs only to depend on Predicate and not List, hence observing the Law of Demeter.

Current Implementation

The following sequence diagram shows the flow of events when the filter h s/physio command is entered by the user to display only HealthWorker objects that possess expertise in physiotherapy:

FilterHealthWorkerSD

Figure 3.6.1.1: Sequence diagram illustrating the interactions between the Logic and Model components when filter command is called.

  1. When the user inputs the full command filter h s/physio, the LogicManager object takes in the command string, and passes it into HealthHubParser using the parseCommand method.

  2. HealthHubParser identifies the command word in the input string, which is filter, and identifies the appropriate CommandParser object to parse the user command.

  3. HealthHubParser strips the filter command word off the user input, and passes the remaining argument string in to a new FilterCommandParser object as corresponding to the filter command word.

  4. FilterCommandParser then checks for a valid CommandMode that corresponds to the first keyword in the argument string. In this case, the keyword h corresponds to the CommandMode.HEALTHWORKER value. FilterCommandParser then creates a FilterHealthWorkerCommand with the Predicate constructed from the fields remaining in the argument string. For full detail on the implementation of the FilterCommandParser logic, see the sequence diagram in figure 3.6.1.2 below.

  5. FilterCommandParser returns the FilterHealthWorkerCommand object to HealthHubParser, which calls the execute method of FilterHealthWorkerCommand.

  6. FilterHealthWorkerCommand uses Java 8’s Predicate and Function libraries to condense all the supplied List<Predicate> into a single Predicate using the and, reduce and stream method calls. After which, it calls the updateFilteredHealthWorker method in Model to set the condensed Predicate on the UniqueHealthWorkerBook in Model, displaying only the HealthWorker that evaluates the set Predicate to true on the GUI.

FilterCommandParserLogicSD

Figure 3.6.1.2 Sequence Diagram that details the interaction that happens within the FilterCommandParser class when it’s parse() method is called.