#Needing help with my first software engineering project (Hospital vital simulator)
1 messages · Page 2 of 1
Okay here's a thing though
there is no point to be doing that in the Observer itself
Actually which is the class that notifies the Observers?
From what I can see it's the DataStorage class
how about this: Make all the necessary checks for all the patient information such as heart beat, blood pressure and such
if there is an abnormality that needs to be handled update the observers with that particular Patient object instead of passing the list with all the Patient objects
you can also add logic to indicate exactly what is wrong with this Patient
it can be some sort of int that holds flags as bits or if you want to make it simpler you can make it a class that just wraps a bunch of booleans like isHeartRateHigh or isBloodPressureHigh
(there are a multitude of ways to implement this, this is just the simplest one I can think of)
this way you also don't need 20 different classes that implement the Observer interface
you just need one that checks those booleans in its update method
and takes action depending on what's flagged and what's not
you could also considering going with Enums to represent different types of issues like HIGH_HEART_RATE or BLOOD_PRESSURE_LOW, etc.
You can but I wrote it out because like that it's hard to indicate multiple things at once
that's why I suggested an int flag variable instead
because you can't really send enums like HIGH_HEART_RATE | BLOOD_PRESSURE_LOW
of course you can make a workaround for it. I just feel like it's not worth the hassle as there are easier alternatives in this case
yeah there's definitely better alternatives what I was suggesting was something I would have to make rn but I have an example here
public enum ExceptionType {
INV_FILE_PATH("INV_FP", "Invalid File Path."),
INV_FILE_TYPE("INV_FT", "Invalid File Type."),
INV_FILE_FORMAT("INV_FF", "Invalid File Format."),
INV_FILE_CONTENT("INV_FC", "Invalid File Content."),
INV_FILE_NAME("INV_FN", "Invalid File Name."),
INV_SESSION_TIMEOUT("INV_SESH_T", "Invalid Session Timeout."),
INV_CONNECTION_TIMEOUT("INV_CONN_T", "Invalid Connection Timeout."),
INV_POOL_SIZE("INV_POOL", "Invalid Pool Size."),
INV_DETECTION_THRESHOLD("INV_DETE_T", "Invalid Detection Threshold.");
private final String shortHand;
private final String desc;
ExceptionType(final String shortHand, final String desc) {
this.shortHand = shortHand;
this.desc = desc;
}
public static Optional<ExceptionType> getExceptionByShortHand(final String shortHand)
throws ExceptionTypeNotFoundException {
return Optional.ofNullable(Arrays.stream(ExceptionType.values())
.filter(exception -> exception.shortHand.equalsIgnoreCase(shortHand))
.findFirst()
.orElseThrow(() -> new ExceptionTypeNotFoundException("No Such Exception Found."))); // Throwing an Exception for Nullable?
}
//region Getters
public String getShortHand() {
return shortHand;
}
public String getDesc() {
return desc;
}
//endregion
@Override
public String toString() {
return "%s, %s".formatted(this.shortHand, this.desc);
}
}
taking this code you can probably provide ranges for the enum lets say something like
BLOOD_PRESSURE(min, max) which can be ints if they fall below the min or go higher than the max then you can just use these instead
i just want one for all the conditions
but this approach is much more time consuming
maybe that's smarter
yeah, that's why I just didn't suggest it
I'll make a simple example
yeah please
Okay so here is a minimalistic example of how this might work
you don't need to follow it like some guide book, it's just something I quickly wrote up.
Here is your Observer interface:
public interface Observer {
class PatientState{
boolean highDiastolic;
boolean highSistolic;
boolean highHeartRate;
boolean isOk;
}
void update(Patient patient,PatientState state);
}
Here is the implementation for the Observer interface:
public class ObserverImpl implements Observer{
@Override
public void update(Patient patient, PatientState state) {
if(state.highHeartRate){
//do something if the heart rate is high
}
if(state.highSistolic){
//do something if sistolic blood pressure is high
}
if(state.highDiastolic){
//do something if diastolic blood pressure is high
}
}
}
Here is the Patient class:
public class Patient {
public int systolicBloodPressure;
public int diastolicBloodPressure;
public int heartRate;
}
and here is the DataStorage class:
import java.util.ArrayList;
import java.util.List;
public class DataStorage {
List<Patient> patients = new ArrayList<>();
List<Observer> observers = new ArrayList<>();
/*Logic here for adding patients to the list or whatever else is needed...*/
public void addObserver(Observer obs){
observers.add(obs);
}
public void removeObserver(Observer obs){
observers.remove(obs);
}
public void checkAbnormalities(){
for (Patient p :patients) {
Observer.PatientState curState = checkPatient(p);
if(!curState.isOk){
fireAbnormalEvent(p,curState);
}
}
}
private void fireAbnormalEvent(Patient p, Observer.PatientState state){
for(Observer obs:observers){
obs.update(p,state);
}
}
private Observer.PatientState checkPatient(Patient p){
Observer.PatientState state = new Observer.PatientState();
if(p.diastolicBloodPressure >140){
state.highDiastolic=true;
}
if(p.systolicBloodPressure>140){
state.highSistolic=true;
}
if(p.heartRate>80){
state.highHeartRate=true;
}
state.isOk= !state.highSistolic && !state.highDiastolic && !state.highHeartRate;
return state;
}
}
Okay hm
you can copy them over somewhere so they can be formatted and not squished
Yeah I was thinking of doing the one above
But it didn’t work for some reason
I think the class structure is the most confusing for me
Why is patient data less general than patient
Why is- you know what nevermind
yeah also the PatientData class seems obsolete
just store all the Patient data as fields in the Patient class
It's not that you can't do it like that
but in my opinion it's way overcomplicating things
Well I’m in agreement
Okay so let me see if I’m understanding you implementation right
The patient state class is the main observer object. It keeps track of all conditions.
The second thing you wrote could just be like the alert generator class actually
by the way I would just like to mention that I think that the observer pattern here is pointless as well
Why’s that
because it's unlikely you would need more than one object to do the handling of a Patient with abnormalities
let me modify the code a little bit to explain what I mean
Okay
okay so here is the new stuff
instead of an Observer interface we have this:
public interface AbnormalityHandler {
class PatientState{
boolean highDiastolic;
boolean highSistolic;
boolean highHeartRate;
boolean isOk;
}
void handlePatientWithAbnormalities(Patient p,PatientState state);
}
the implementation is this:
public class AbnormalityHandlerImpl implements AbnormalityHandler{
@Override
public void handlePatientWithAbnormalities(Patient p, PatientState state) {
if(state.highHeartRate){
//do something if the heart rate is high
}
if(state.highSistolic){
//do something if sistolic blood pressure is high
}
if(state.highDiastolic){
//do something if diastolic blood pressure is high
}
}
}
and this is the modified DataStorage class:
import java.util.ArrayList;
import java.util.List;
public class DataStorage {
List<Patient> patients = new ArrayList<>();
AbnormalityHandler handler;
DataStorage(AbnormalityHandler handler){
this.handler=handler;
}
/*Logic here for adding patients to the list or whatever else is needed...*/
public void checkAbnormalities(){
for (Patient p :patients) {
AbnormalityHandler.PatientState curState = checkPatient(p);
handler.handlePatientWithAbnormalities(p,curState);
}
}
private AbnormalityHandler.PatientState checkPatient(Patient p){
AbnormalityHandler.PatientState state = new AbnormalityHandler.PatientState();
if(p.diastolicBloodPressure >140){
state.highDiastolic=true;
}
if(p.systolicBloodPressure>140){
state.highSistolic=true;
}
if(p.heartRate>80){
state.highHeartRate=true;
}
state.isOk= !state.highSistolic && !state.highDiastolic && !state.highHeartRate;
return state;
}
}
I had tried something like hat before
But was a little idk
I guess the thing is I want to make sure I understand any solution I implement
But this is a good place to start
well I'd say that for your particular situation this is the best approach
I’m understanding a bit better now
you can move the patient state checking logic to the AbnormalityHandler interface as well if you would like
ah
in the checkAbnormalities method there should be a check for whether the patient is ok before firing the event
of course you can do that logic check in the actual AbnormalityHandler as well
it's just checking the isOk boolean
This is a good place to get started for me
I understand this solution more. I’ll trace the code and see if I can make some progress with it
yeah. I'd say that in your situation this is probably the best approach
good luck!
Thank you so much for the help! Gonna do some code tracing and see where I can polish it up.
alright, feel free to ask again if something else comes up.
@vernal phoenix hey, one further question
i like the way you did this and i'm using many aspects of it but one questions is if the patient class does not allow for a direct way to get patientID, would it be wise to make patient class and patientID kind of one
I am not sure exactly what you mean by that
can you show me an example? Perhaps just your Patient class will be enough
I will probably be going to bed soon though so I'd say the earliest I'll respond after a bit is tomorrow
No problem
still here so maybe we can get this sorted out before I go to bed
I don’t know. I feel totally overwhelmed with this shit
Basically
I like the interface for the different states
But the issue is in the logic for logging it
I want to get the patient’s Id
The thing is
There’s not accessor for the patient id in the patient class!
Why?
Cuz fuck you that’s why!
It’s so frustrating
can you not just make a getter?