Design Patterns in Healthcare domain
Tags: softwaredesignpattern, softwaredevelopment, healthtechnology, antipattern
Published: 2020-06-25 14:54:19

---
title: Design Patterns in Healthcare domain
published: true
date: 2020-06-07 13:22:33 UTC
tags: softwaredesignpattern,softwaredevelopment,healthtechnology,antipattern
canonical_url: https://medium.com/@bukhorimuhammad/design-patterns-in-healthcare-domain-2128994f9b0e
---

_Same old design patterns, from healthcare use cases_

For those of you who don’t know, design pattern is one of the fundamental concepts in software engineering that will help you manage pieces of your system by reducing complexity and isolating independent components so that frequent change can be performed smoothly.

> A pattern describes a **problem that occurs over and over** again in our environment, and then **describes the core of the solution** to that problem in such a way that **you can use this solution a million times** over, without ever doing it the same way, twice  
>  — Christopher Alexander, A Pattern language

![](https://cdn-images-1.medium.com/max/140/1*YBbJhIUmblFXyluBa9CWzA.jpeg)<figcaption>Design Patterns by GoF</figcaption>

One of the famous books regarding software design pattern is created by Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides).

![](https://cdn-images-1.medium.com/max/113/1*qeWhEvXBjWs0IFE9MI8Q3g.gif)<figcaption>A System of Patterns</figcaption>

There is also a good book by Gang of Five (5 completely different persons than Gang of Four) which gives a bigger scope perspective in software engineering patterns.

In this series of articles, I will try to dissect and discuss some of the patterns contained in those 2 books with sample cases/problems from the healthcare domain. I do realize that those books discussed more towards the context of Object-Oriented Principle and might not apply in some non Object-Oriented language. But the patterns alone are worth to discuss and might be beneficial in some general cases.

Before starting the pattern discussions, we have to know how to model real life concept/object type and phenomenon/object instance. We usually model those with UML (Unified Modelling Language) and that’s what we’ll use most of the time while discussing design patterns.

Since we’re going to work with lots of UML diagram in this article series, let’s recall some of the UML notation:

![](https://cdn-images-1.medium.com/max/1024/1*K_9IUd6ADpHWSnvva61xUA.png)<figcaption><a href="https://www.omg.org/spec/UML/2.5.1/PDF">https://www.omg.org/spec/UML/2.5.1/PDF</a></figcaption>

There will be some UML doodle similar to the one above in this series so bear with my chicken scratch handwriting :)

Before crafting UML diagram, there are 4 important concepts that you need to remember for modeling:

- **Abstraction** : Can the object instances be generalized into type or sub-type?
- **Inheritance** : Which type is the ‘parent’ of the other type? (Car vs Sports Car)
- **Encapsulation** : Which part of the data/behavior is exposed to the outer world?
- **Polymorphism**

![](https://cdn-images-1.medium.com/max/1024/1*H-oKaSp6iqUcuK9ZbrQbTg.png)<figcaption>PSE 1920 TUM: Polymorphism hierarchy</figcaption>

Besides doing that, you also want to achieve **low coupling and high cohesion.** Having low coupling means that the dependencies between subsystems are low and high cohesion means that the dependencies among classes in one system are high. To achieve this property there are some things that you can do :

- **_Principle of Least Knowledge/Law of Demeter_**  
The intuition for this is rather easy, if you call multiple objects e.g. objectA.getB.getC.doThings() then you might violate this principle.
- **_Ask, don’t tell_**  
Instead of directly modifying object internals (tell), call a method/API that will modify such internal (ask).

> In this article, I will take some of the patterns and try to give some context and examples related to healthcare domain.

### **I. Structural Patterns**

This pattern group aims to reduce coupling between classes, enabling future extensions (by introducing abstract class) and encapsulate complex structures.

#### **Delegation Pattern** on Activity Delegation between Doctor and Nurses

> In many states, physicians can delegate their activities to nurses, physician assistants or other medical professionals to deliver care more efficiently and effectively.  
> [http://lawatlas.org/datasets/physician-scope-of-practice-1509022789](http://lawatlas.org/datasets/physician-scope-of-practice-1509022789)

![](https://cdn-images-1.medium.com/max/1024/1*nwumzZeGi_eHU0hmKGkRVA.png)

I can imagine that during the daily tasks of a doctor, there are some activities that can be delegated to another role that is better suited or even more skilled in that one specific action. That’s why sometimes you have doctor prescribe and/or apply the first medicine but then followed up by nurses.

We can model that kind of scenario using delegation pattern. Simply by having Doctor class to store reference to Nurse class and when needed, call the Nurse object for action delegation.

> if (doctor.busy) nurse.apply()

#### **Adapter Pattern** on API Development in Legacy Hospital System

Consider this scenario:

> A hospital has already been running for 100 years with stable in-place system.

You are a new and modern tech division in the hospital, wants to create mobile app, needing API that consumes the data from legacy system as well as collecting new data from other sources

![](https://cdn-images-1.medium.com/max/1024/1*UM-Iw0NgcxLUHn6aU8qHCg.png)<figcaption>some kind of UML Diagram</figcaption>

One way to connect those 2 systems is to create an adapter. In the UML diagram above, Legacy Adapter acts as a translator/connector between 2 systems. This can be done by implementing interfaces or extending parent class (and override some methods) from the new system and then make a delegation call (blue arrow) or calling the superclass method (inheritance green arrow) to get the value.

Please be aware that you might need to do some parsing/conversion process in the adapter to ensure that the request and response data is in a valid format.

#### **Bridge Pattern** on Medicine Procurement from Multiple Sources

[Medicine procurement in hospital pharmacies of Nepal: A qualitative study based on the Basel Statements](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0191778)

> It was found that the majority of hospital pharmacies in Nepal reported using an expensive direct-procurement model for purchasing medicines.

Since direct-procurement in Nepal is expensive, we want to provide cheaper option by having an auction based or competitive-procurement. But we don’t want to disrupt an already stable system. There is also a problem that some branches might already have their own customization. This calls for a Bridge Pattern.

In this scenario, our Bridge Pattern consists of

- Application Domain:  
This is your hospital/hospital system
- Solution Domain:  
This is where you get your medicines using some procurement model

Procurement can happen with direct or competitive procurement model, and in this case each hospital branch have the the liberty to choose any model they prefer.

![](https://cdn-images-1.medium.com/max/1024/1*fUjHxqg6mUL3fNOuAEuDHg.png)

By creating a bridge pattern between abstraction of hospital and procurement, we can strictly define each branch to have procurement model but since the subclass can override the superclass then each branch can choose their preferred model and new branch can also choose their preferred model. Changing model also easy, just add implementation of procurement and change branch that wants to use that new model.

But be careful with **Degenerate Bridge** : where the application or the solution domain doesn’t have a subclass/subtype (yet). This might increase complexity without any clear benefits.

> In a sense, Adapter pattern might seem similar to Bridge pattern. But “Adapter makes things work after they’re designed; Bridge makes them work before they are. [GoF, p219]”

#### **Proxy Pattern** on Patient’s Guardian/Decision Proxy

[Why all adults need a healthcare proxy](https://hhma.org/blog/why-all-adults-need-a-health-care-proxy/)

The article above argues that we should always have a healthcare proxy in for emergency cases. As a healthcare system developer, we want to cater to this scenario hence we’ll implement Proxy Pattern in our hospital system.

There are 3 types of Proxy Pattern:

- Caching/Remote Proxy  
The proxy object is used for information caching (local representative for an object in a different location)
- Substitute/Virtual Proxy  
This proxy is used for a stand-in object in case the real object takes quite a lot of time/memory to instantiate
- Access Control/Protection Proxy  
This proxy provides access control to the real object

In this particular case, the guardian acts as access control proxy. If the real patient can actually do / willing to do said action that it will do it otherwise the proxy gets to decide.

![](https://cdn-images-1.medium.com/max/941/1*IIEEriq9Dep4oq3MgAMGpA.png)<figcaption>scratch UML for proxy pattern</figcaption>

> if (competent) inPatient.agreeToProcedure()

> **else patientP** roxy.agreeToProcedure()

### **II. Behavioral Patterns**

By applying patterns in this group you can answer “Who does what?” questions, e.g which algorithm is used for some problems, or which object instance to use. This will also simplify control flow and enable a better understanding of your program data flow.

#### **Strategy Pattern** on Patient-Centered Care approach

[Eliciting patient treatment preferences: A strategy to integrate evidence-based and patient-centered care.](https://www.ncbi.nlm.nih.gov/pubmed/16965313)

One of the strategy described in article above is to elicit patient preferences via written description. With some preferences given, there will be differences in patient care/treatment. During the hospital system development, this scenario can be handled by utilizing strategy pattern

![](https://cdn-images-1.medium.com/max/1024/1*FXbG00-7AzlCI46xz-i2vw.png)

The difference with Bridge Pattern is that if you use a bridge pattern, the patient (depending on the preference) will receive the type of treatment that he/she wants before system runtime while in strategy pattern, the treatment will be decided from patient preferences and can be changed at runtime if the preferences of the patient changed.

#### **State Pattern** on Medical State representation

Sometimes, hospital describe patient’s condition in a medical state jargon. Even though this is not commonly used clinical term, it will serve as a nice example for the needs of using State Pattern.

[Medical state](https://en.wikipedia.org/wiki/Medical_state)

State Pattern is used to help object control their behavior by changing its internal state.

Per Wikipedia’s description, there are several Medical States:

**Undetermined**  
Patient awaiting physician and/or assessment.  
**Good**  
[Vital signs](https://en.wikipedia.org/wiki/Vital_signs) are stable and within normal limits. Patient is conscious and comfortable. Indicators are excellent.  
**Fair**  
Vital signs are stable and within normal limits. Patient is conscious, but may be uncomfortable. Indicators are favorable.  
**Serious**  
Vital signs may be unstable and not within normal limits. Patient is seriously ill. Indicators are questionable.  
**Critical**  
Vital signs are unstable and not within normal limits. Patient may be unconscious. Indicators are unfavorable.  
**Dead**  
Vital signs have ceased. Patient has died.

![](https://cdn-images-1.medium.com/max/1024/1*s8YbNaB5odDnhV720FD7ug.png)<figcaption>scratch UML for Medical State</figcaption>

Every state can move to another state depending on the patient’s condition.

> patientState.handle(…) can results in different actions depending on the current Medical State

There might be a question on where to handle state change, should it happen in the context class (TreatmentContext) or should it happen in concrete class (Medical States). I would say that this is up to personal preferences, but handling it in the concrete class will reduce the conditional block and making it simpler to add more state and/or see the limitation on each state.

#### **Observer Pattern** on Integrated Patient Information

[Inadequate availability of patient information is a major cause for medical errors and aﬀects costs in healthcare. Traditional information integration in healthcare does not solve the problem.](https://www.researchgate.net/publication/220796284_A_mediated_publish-subscribe_system_for_inter-institutional_process_support_in_healthcare)

An improvement for the information exchange is needed. The goal is to provide better information exchange between institutions (see Broker Pattern), or in smaller cases — between displays in a hospital counter. Let’s discuss the this smaller scope using observer pattern.

There are 2 key parts in observer pattern:

- Observable object / Publisher
- Observers / Subscribers

Imagine that in the same examination room, you have different screen / Graphical User Interface (GUI) used by the nurse to take your blood pressure, check for previous diseases, etc. There is also another GUI for the doctor to input more extensive treatment and diagnosis.   
Wouldn’t it be nice if when the nurse enters your measured data, the GUI for the doctor is also updated? We can achieve this by applying an observer pattern with patient information as observable object

![](https://cdn-images-1.medium.com/max/1024/1*E5mcqOBNpNF_AJ7zyemxEw.png)<figcaption>scratch UML for publish-subscribe scenario</figcaption>

Each GUI must have Observer implementation so that they can observe the patient information. And since they also modifying the Observable object, all changes will be observed and updated by other GUIs.

### **III. Creational Patterns**

Sometimes to create something there are complex process involved and Creational Patterns are one collection of design pattern trying to improve the implementation of those complex processes. By applying patterns in this group you can create a simplified view to understand those processes in a glance. This will also make the creation process independent hence reducing dependency and coupling.

#### **Abstract Factory Pattern** on Doctor Skills Composition

Doctor can have multiple skill set. How do we properly model this scenario using Abstract Factory pattern?

Before starting with this pattern, we need to address the difference between Factory (Method) pattern vs Abstract Factory pattern.

**Factory Method**  
As the name implies, Factory Method is a method / function that has an objective to instantiate one object.

**Abstract Factory**  
Utilizing full class as Abstract Factory, we can create more complex object instantiation consisting of different classes composing that said object.

Now let’s consider the action of adding new doctor to the hospital. Every doctor has their degree and specialization and we might encounter one situation where we have a very competent doctor with multiple and maybe specialized skills. How can we create new doctor object with all the skills information and dependencies?

In this case, we can generalize few things, such as:

- Hospital has doctors
- _Doctor_ has _Degree_(s)
- Degree has a specific _Degree Factory_ extending default (general physician) degree factory
- Degree factory returns degree containing multiple skills given specific factory class
- For a new degree, it’s as easy as add new degree factory with _composeSkills()_ method containing all the required skills

![](https://cdn-images-1.medium.com/max/1024/1*pahWkDJjiqYhkULTooHywg.png)<figcaption>scratch UML for Abstract Factory Pattern</figcaption>

### **IV. Architectural Patterns**

An architectural pattern is a special set of pattern applied to software architecture problem within a given context. In this section we will discuss several samples of Architectural Pattern.

#### **Blackboard System** for Evidence-Based Diagnosis

[Understanding evidence-based diagnosis : Diagnosis](https://www.degruyter.com/view/j/dx.2014.1.issue-1/dx-2013-0003/dx-2013-0003.xml)

> “ How do we minimize the cognitive errors inherent to a task like diagnosis? The answer is even less clear, but computerized diagnostic support tools may have a role.”

One approach to model computerized diagnostic support is by using Blackboard (behavioral) pattern implemented in Blackboard system (architecture). Intuitively, you can imagine blackboard system as a room filled with experts discussing problems and putting solutions and opinions in the blackboard to achieve one final consensus/result.

In general, blackboard system consists of 3 big elements:

- **Blackboard** is the repository of the problem, partial solutions and new information (hypotheses, etc)
- **Knowledge Source** that reads anything placed in the blackboard (input) and place new information created by them on the blackboard.
- **Control** that governs the flow of problem-solving activity in the system.

Also in order to create blackboard system, there are 6 steps that will be beneficial to follow:

1. Define the problem (and make sure there’s no algorithmic solution for it)
2. Define the solution space
3. Identify Knowledge Sources
4. Define the Blackboard
5. Define the Control
6. Implement Knowledge Sources

Let’s apply those 6 steps in our case

1. The problem : Evidence based diagnosis  
Domain: Healthcare  
Requirement: Given symptoms, patient health data & history, provide supporting diagnosis output  
Actors: Doctor, Patient, Nurses
2. Solution space :  
In the solution space, we need to identify the existence of top-level and intermediate solutions. A top level solution might indicate a flu diagnosis while intermediate solution might specify more details like possibility of dengue fever.   
For a complex diagnosis, partial solution might be needed as well. Such as giving cluster of diseases might occur given the observed symptoms and patient’s history.
3. Knowledge Sources:  
Different records of past diagnosis, organized (e.g. grouped by city)  
Inputs: Patient health data, Reported symptoms  
Outputs: Solution candidate as different diagnosis with confidence level
4. Defining Blackboard:  
We need to decide the data representation used in the blackboard, such as JSON with added metadata.
5. Defining Control:   
How are we going to process all the data provided from various Knowledge Sources? How and who are going to construct and verify the hypothesis? What constitutes an acceptable solution?   
In this stage, an expert help is necessary so collaboration is a must.
6. Knowledge Source implementation  
To implement Knowledge Sources, we need to define condition and action. We can utilize multiple arrays of techniques such as Bayes rules, classification algorithms, rule based system, or any of the computational intelligence methods.

![](https://cdn-images-1.medium.com/max/1024/1*BGT7v2GPAjM1tAkv9IAaEQ.png)<figcaption>scratch UML for Blackboard System</figcaption>

#### **Client-Dispatcher-Server** for System with High Availability

> Once, I visited a clinic because I got a fever. Their system is under maintenance from 11:00–13:00 and I need to wait until it’s up before my medical data can be processed.

True story. And we can avoid that by implementing simple client-dispatcher-server

Healthcare is a critical field. A single mistake can cost human life. When I check myself in that said clinic during mid day, I observed that they have tablets and laptop but not using it. Curious, I asked: why do you have those devices but not using it? Surprisingly they said: Our system is usually under maintenance during this time so just to be safe we use paper and we will process the data later. Of course there might be multiple reasons why this happen but having only one server without backup might be the cause, so when there is a scheduled update then the client will be unable to connect to that server. We should provide several servers as backup so we can have zero down time deployment and update. But how are we going to manage those servers and the client connections?

Client-Dispatcher-Server architecture will help manage your system by introducing a dispatcher subsystem that manages connection between multiple clients and multiple servers so that updates can be done without making the server down.

To implement Client-Dispatcher-Server there are some steps that is useful to follow

1. Identify subsystem that act as clients, servers and dispatchers
2. Decide on the communication mechanism to be used for the protocols
3. Specify the protocols between components
4. Decide naming scheme for dispatcher
5. Implement the dispatcher
6. Implement client and server

Note: To be technically accurate, client-dispatcher-server architecture should enable direct client-server connection after name resolve so if you’re using load balancer to manage multiple servers you need to configure direct server return ([https://www.haproxy.com/blog/layer-4-load-balancing-direct-server-return-mode/](https://www.haproxy.com/blog/layer-4-load-balancing-direct-server-return-mode/)), sticky session or the combination. But in real life this usually doesn’t matter much.

#### **Broker Pattern** for Integrated Patient History

While in Observer Pattern we discuss how each hospital units keep it touch with the data, there is also the need to have integrated patient history between hospitals which means all data must be passed remotely. The question is, how to accommodate this use case in our system?

Broker Pattern, specifically message broker pattern can be used in this scenario.

[Message broker](https://en.wikipedia.org/wiki/Message_broker)

While implementing the pattern you need to provide client proxy and server proxy in order to make sure that there is no compatibility problem between different platforms and implementations as well as hiding inter-process communication details between said party to broker. The proxy will also takes care of marshaling (serialize) and unmarshaling (deserialize) messages.

There are lots of existing libraries / tools that can help you with the implementation of message broker pattern. Some of the most popular ones are [RabbitMQ](https://www.rabbitmq.com/) and [Apache Kafka](https://kafka.apache.org/), among many others.

By understanding several different patterns and actively implement them, we should develop an intuition on how to solve some problems. There are a lot more patterns than described in this article and I personally recommend [SourceMaking](https://sourcemaking.com/)as your first stop on understanding further patterns. But we have to be careful to not fall into AntiPatterns trap, especially since [sometimes, detecting Anti Pattern is hard](https://www.linkedin.com/pulse/anti-pattern-how-obvious-bukhori-aqid/).

_Hope this helps!_