The Kirpal Sagar Charitable Hospital is a small hospital in Punjab, India with around 30 to 50 beds. Over the next decades it is envisioned to grow up to 500 beds. In order to handle the internal processes at that scale a health care information system is required. While there is already a software system in place, it doesn't provide optional support for that growth path.
One option for reaching this goal is to build a custom solution from scratch. In contrast to adjusting the hospital processes some standard software this approach allows to adjust the software to the specific requirements. For example the billing needs to support a discount scheme ranging from 0 to 100%, according to the life circumstances of the patient. Also at some point the patient recordings should be synchronized with the student accounts of the Kirpal Sagar Academy, etc.
This blogpost is a description of an architectural prototype for this approach.
The program is a Java based web application, to be deployed in the local area network of the hospital. The reason for this choice is that the Java is currently one of the most common solutions for enterprise applications. Furthermore, it has a large ecosystem with plenty of open-source tools and libraries. Last but not least, there are books and tutorials for all things Java available.
As application framework Spring is being used. The Spring Core framework provides features like dependency injection, data access, and transaction management. With Spring Security access rules for specific URLs can be specified. Spring Data provides an abstraction layer for the database. The Spring Boot project simplifies working with Spring by providing features like automatic configuration and dependency management for commonly used libraries.
For the creation of the HTML pages Apache Wicket is applied. This enables the application to be deployed in a single package, so that only one application process and the database server need to be monitored. Another advantage of Wicket is that is allows using object-oriented design techniques for the composition of the web elements. Those HTML components can be developed independently by web designers as no knowledge about the backend is required for this. Beside this Wicket offers a wide range of features to build advanced web applications, e.g. user sessions, role-based authentication, caching, and dynamic page updates with AJAX.
Software systems tend to grow into extreme complexity over time. In order to keep this complexity under control they need to be properly structured. In the everyday life various means are applied for keeping things in order. E.g. screws are stored in little boxes. Different sorts of screws are kept together in big boxes. Those big boxes are put along with other materials and tools into shelves. The next level of granularity is a room where related shelves are located. Multiple rooms form a building which is dedicated to a particular purpose.
There are also different means available for structuring Java applications within different levels of granularity. The finest level of structure are methods. Related methods and variables are kept together in classes. Multiple classes that provide some capability are grouped into packages. Multiple packages belonging to a certain aspect are bundled in modules via the Java Platform Module System (JPMS), OSGi bundles, Maven multi-module projects, or Gradle multi-project builds. The application as a whole then provides a set of capabilities for a business domain.
The ideal for this application is that methods and classes are structured with the SOLID design principles. The classes are then grouped with the package by feature pattern in order to keep the focus on the business domain. For the separation of the different contexts the Gradle based option is applied. This offers a better Spring integration than JPMS and OSGi while it is still possible to hide the implementation details of the modules via the Java Library Plugin.
At the core of the application are the domain modules which represent the different areas of the clinical services and administrative functions of the hospital. Each of them has two nested sub-modules. One is the module's interface (API) which is accessible for all the other modules. The other is for the implementation details (Impl). Here things like database access and calculation of the business logic are taking place, without other modules knowing about this. Thus the implementation details can be changed without any impact on the clients of the module's API. For example, the data storage could potentially be changed from PostgreSQL to a MongoDB database.
When one module knows about the contents of another, it is said to have a dependency thereupon. Gradle prohibits circular dependencies; that both know about each other. In case they need to collaborate nevertheless, they can use the publish-subscribe interaction model. With this one component can publish messages to a third-party and another component can subscribe there to get notified about those kind of messages it is interested in. This can be implemented with the help of the observer design pattern. However, by using the Spring Application Events feature this concept can be applied without the need to implement it from scratch. So for example, the Patient Management module can publish a
PatientCreatedEvent when a new patient was registered. The Reports module can then request to get a notification when this happens and thereupon process it accordingly. In this way the Reports module can potentially be restructured without the need to change anything in the Patient Management module.
The User Interface module contains a package for each computer workstation in the hospital. It can leverage the APIs from all domain modules in order to orchestrate the workflows. Due to technical reasons the Spring application class and its configuration are also located there.
Wicket connects the Java classes and HTML files via naming conventions. For each web page class it tries to find a HTML file with the same name. If this isn't there, it tries to find a HTML file with the name of the parent class, etc. Using object-oriented programming techniques, the pages can be arranged by composition and inheritance. When a page or component is finally being rendered, the HTML elements with a Wicket ID attribute are getting their information from the respective instructions in the Java classes. There the domain services are available with the help of the Spring framework.
In order to apply the same look and feel everywhere, there is a common base class for all web pages (ApplicationFrame.java / ApplicationFrame.html). Derived from this there is a base page for each respective workstation which provides a template method implementation for the link in the "Home" icon (e.g. RegistrationPage.java). From that all pages of a workstation are derived (e.g. RegisterPatientPage.java). The leaf pages do not specify HTML on their own but instantiate components and then provide them via another template method as page content. The HTML of the parent class is then filled with those components, i.e. a Dashboard (Dashboard.java / Dashboard.html) or Activity (Activity.java / Activity.html).
Developing a hospital information system is actually a major undertaking, rather a life task. So maybe would be better to use an existing open source system like Bahmni and pay consultants to introduce, customize, and maintain it. However, given that there are already two custom-developed programs in place for the school administration and inventory management, it doesn't seem unrealistic to add a third one for the hospital. With this there is a chance to have a system which is optimized for the requirements of the facility.
What is your impression of this approach? How far do you think can we get with it? Where do you see its strengths and weaknesses?
Any form of constructive feedback is most welcome.
Level up every day