#Needing help with my first software engineering project (Hospital vital simulator)

1 messages · Page 2 of 1

hybrid thunder
#

and checks if the heart beat is above or below the critical points

vernal phoenix
#

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

pallid hornet
vernal phoenix
#

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

pallid hornet
#

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

hybrid thunder
pallid hornet
#

but this approach is much more time consuming

hybrid thunder
#

maybe that's smarter

vernal phoenix
vernal phoenix
hybrid thunder
#

yeah please

vernal phoenix
#

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;
    }

}
hybrid thunder
#

Okay hm

vernal phoenix
#

you can copy them over somewhere so they can be formatted and not squished

hybrid thunder
#

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

vernal phoenix
#

yeah also the PatientData class seems obsolete

hybrid thunder
#

I thought so

#

But they made it that way

vernal phoenix
#

just store all the Patient data as fields in the Patient class

hybrid thunder
#

I’m afraid of changing too much

#

But yeah

#

I agree with you

vernal phoenix
#

It's not that you can't do it like that

#

but in my opinion it's way overcomplicating things

hybrid thunder
#

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

vernal phoenix
#

by the way I would just like to mention that I think that the observer pattern here is pointless as well

hybrid thunder
#

Why’s that

vernal phoenix
#

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

hybrid thunder
#

Okay

vernal phoenix
#

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;
    }

}
hybrid thunder
#

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

vernal phoenix
#

well I'd say that for your particular situation this is the best approach

hybrid thunder
#

I’m understanding a bit better now

vernal phoenix
#

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

hybrid thunder
#

Yeah

#

So we’d pass the patient’s record to the handler

vernal phoenix
#

of course you can do that logic check in the actual AbnormalityHandler as well

hybrid thunder
#

And the. Just

#

Yeah

vernal phoenix
#

it's just checking the isOk boolean

hybrid thunder
#

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

vernal phoenix
#

yeah. I'd say that in your situation this is probably the best approach

#

good luck!

hybrid thunder
#

Thank you so much for the help! Gonna do some code tracing and see where I can polish it up.

vernal phoenix
hybrid thunder
#

Haha I probably will

#

Thanks dude

hybrid thunder
#

@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

vernal phoenix
#

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

hybrid thunder
#

No problem

vernal phoenix
#

still here so maybe we can get this sorted out before I go to bed

hybrid thunder
#

I don’t know. I feel totally overwhelmed with this shit

hybrid thunder
#

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

vernal phoenix
#

can you not just make a getter?

hybrid thunder
#

I did but it was a bit ridiculous

#

I’ll post it again later because I have to work on something