Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleDel 1 - første trinn av Doctor, Patient og TreatmentUnit-klassene (20%)

Denne første versjonen av systemet består av tre klasser. Patient er en tom klasse. Doctor-klassen har en assosiasjon til en Patient. TreatmentUnit holder rede på hvilke pasienter og doktorer som finnes, og styrer avvikling av behandlingskøen. Pasienter som har blitt behandlet av en lege fjernes fra systemet. Pasientene har altså ingen (helse)tilstander her.

Expand
titleSkjelett til del 1

/*Er klar over mellomrom mellom linjene, men det kommer av kopiering fra Inspera (for å få farger...)*/

/**

 * A doctor has the capacity to treat one patient at a time.

 */

public class Doctor {

       // Internal variables go here:

   

       /**      

* @return the patient this doctor is treating, or null if s/he isn't currently treating any patient.

        */

       public Patient getPatient() { // 1a

              ...

       }


       /**

        * @return true if this doctor is currently treating a patient, otherwise false.

        */

       public boolean isAvailable() { // 1a

              ...

       }


       /**

        * Sets the patient that this doctor is treating, use null to indicate s/he isn't currently treating any patient.

        * @param patient

        */

       public void setPatient(final Patient patient) { // 1a

              ...

       }

}

 


/**

 * A class for managing a set of doctors and the patients they're treating.

 * When doctors or patients arrive, it is made sure that patients are treated as soon as possible.

 */

public class TreatmentUnit {


       // Internal variables go here: // 1b

      

       /**

        * Adds a doctor and makes sure s/he starts treating a patient, if one is waiting.

        * @param doctor

        */

       public void addDoctor(final Doctor doctor) {  // 1b

              ...


       }


       /**

        * @return the currently available doctors

        */

       public Collection<Doctor> getAvailableDoctors() {  // 1b

              ...

       }


       /**

        * Adds a patient to this treatment unit, and makes sure treatment starts if any doctor is available.

        * Otherwise the patient is queued for treatment when a doctor becomes available.

        * @param patient

        */

       public void addPatient(final Patient patient) {  // 1b

              ...

       }


       /**

        * @param pred the predicate that the doctor must satisfy

        * @return some doctor satisfying the predicate

        */

       public Doctor getDoctor(final Predicate<Doctor> pred) {  // 1b

              ...

       }


       /**

        * Find the doctor, if any, that treats the provided patient.

        * @param patient

        * @return the doctor treating the provided patient, or null, of the patient isn't currently being treated

        */

       public Doctor getDoctor(final Patient patient) {  // 1b

              ...

       }


       /**

        * Find all patients that are not currently being treated.

        * @return the patients not currently being treated.

        */

       public Collection<Patient> getWaitingPatients() {  // 1b

              final Collection<Patient> result = new ArrayList<>();

              ...

       }


       /**

        * Finds a waiting patient and sets him/her as the provided doctor's patient.

        * @param doctor the doctor for which a patient to treat should be found

        * @return true if a patient for the provided doctor was found, false

 * otherwise.

        */

       private boolean startTreatment(final Doctor doctor) {   // 1c

              ...

       }


       /**

        * Finds an available doctor for the provided patient, and sets that doctor to

 * treat the patient.

        * @param patient the patient for which a treating doctor should be found.

        * @return true if a doctor for the provided patient was found, false

 * otherwise.

        */

       private boolean startTreatment(final Patient patient) {   // 1c

              ...

       }


       /**

        * Removes the link between doctor and patient, after treatment is finished.

        * Since the patient is fully treated, s/he is removed from this treatment

 * unit.

        * Also ensure the doctor starts treating another patient.

        * @param doctor the doctor that has finished treating his/her patient.

        */

       public void treatmentFinished(final Doctor doctor) {  // 1c

              ...

}

 


Oppgave a)

 Skriv ferdig Doctor-klassen i henhold til skjelettet, altså nødvendige innkapslingsmetoder og isAvailable. Patient er så langt en tom klasse, du trenger ikke implementere denne.

Expand
titleLF

 

Doctor-klassen er i 1a brukt for å vise grunnleggende forståelse av innkapsling, bruk av interne variable og metoder. Det legges ikke vekt på bruk av final, verken her eller i eksamen forøvrig.

Den interne variable variabelen patient angir hvilken (om noen) pasient som er under av denne doktoren nå. Den bør kapsles inn, altså gjøres private, samt ha vanlige public get/set-metoder. Metoden isAvailable() skal returnere hvorvidt patient for tiden er null eller ikke. Vi trenger ingen konstruktør, da det ikke er naturlig at doktorer behandler en pasient allerede ved opprettelsen.


Code Block


public class Doctor
{

 

               private Patient patient; // 1a

 

               public Patient getPatient() { // 1a

                              return patient;

               }

 

               public boolean isAvailable() { // 1a

                              return getPatient() == null;

               }

 

               public void setPatient(Patient patient) { // 1a

                              this.patient = patient;

               }

}

 
 { 
               private Patient patient; // 1a
 
               public Patient getPatient() { // 1a
                              return patient;
               }
 
               public boolean isAvailable() { // 1a
                              return getPatient() == null;
               }
 
               public void setPatient(Patient patient) { // 1a
                              this.patient = patient;
               }
}


Merk at javadoc-en for isAvailable var motsatt av logikken vi ønsket, derfor trekkes det ikke om logikken er snudd.

Vanlige feil (så langt): Feil synlighetsmodifikatorer.

Oppgave b)

Skriv følgende deler av klassen TreatmentUnit, basert på beskrivelsen i skjelettet:

  • Avgjør og implementer den interne representasjonen av pasienter og doktorer.
  • addDoctor, addPatient, getAvailableDoctors, og getWaitingPatients.
  • getDoctor: Denne finnes i to versjoner, med og uten bruk av Predikat. Du skal skrive begge disse versjonene.

Vær obs på at enkelte av disse metodene bør kalle startTreatment fra 1c.

Expand
titleLF
 

En TreatmentUnit har behov for å lagre en samling med doktorer som jobber der og pasienter som skal behandles (eller er under behandling). Vi har valgt vi en Collection for å lagre hver av disse, fordi det ikke er behov for indeksbasert tilgang til elementene. En annen (kanskje Set-basert) klasse som beholdt rekkefølge kunne også vært brukt). Merk at vi ikke har egne lister for doktorer som er ledige eller pasienter som venter, selv om det ville gjort noen ting enklere.

Variable skal være private, med begrenset tilgang gjennom public-metoder.

Det er to getDoctor-metoder, hvor getDoctor(Predicate) gjør et søk gjennom alle doktorer, og returnerer den første (om noen) som tilfredsstiller Predicate-parameteret ved kall til dennes test-metode. Den andre metoden getDoktor-metoden, getDoctor(Patient), bruker den første ved å gi inn en lambda (instans av Predicate-grensesnittet) som sjekker om doktoren har registrert denne pasienten som sin.

getAvailableDoctors og getWaitingPatients er nokså like ved at de returnerer en samling objekter fra et større sett, som tilfredsstiller gitte kriterier. Disse kan forenkles hvis en har egne lister for dem, men da blir andre metoder mer kompliserte.

public class TreatmentUnit {

       // Internal - 1b

       private Collection<Doctor> doctors = new ArrayList<>();

       private Collection<Patient> patients = new ArrayList<>();

 

       public void addDoctor(Doctor doctor) { // 1b

             doctors.add(doctor);

             startTreatment(doctor);

   }

 

       public Collection<Doctor> getAvailableDoctors() { // 1b

             Collection<Doctor> result = new ArrayList<>();

             for (Doctor doctor : doctors) {

                    if (doctor.isAvailable()) {

                           result.add(doctor);

         }

      }

             return result;

             // return doctors.stream().filter(Doctor::isAvailable).collect(Collectors.toList());

   }

 

   public void addPatient(Patient patient) { // 1b

             patients.add(patient);

      startTreatment(patient);

   }

 

      public Doctor getDoctor(Predicate<Doctor> pred) { // 1b

             for (Doctor doctor : doctors) {

                    if (pred.test(doctor)) {

                          return doctor;

         }

       }

             return null;

   }

      public Doctor getDoctor(Patient patient) { // 1b

           return getDoctor(doctor -> doctor.getPatient() == patient);

   }

 

      public Collection<Patient> getWaitingPatients() { // 1b

           Collection<Patient> result = new ArrayList<>();

           for (Patient patient : patients) {

               if (getDoctor(patient) == null) {

                       result.add(patient);

               }

    }

         return result;

}

 

Vi forventer her korrekt bruk av løkker. getDoctor(Patient) bør kalle getDoctor(Predicate) for å unngå kodeduplisering.

Oppgave c) - TreatmentUnit: Koble pasient og doktor

 Hver gang en ny pasient eller lege er lagt til, eller en lege har avsluttet en behandling, bør TreatmentUnit forsøke å koble en ledig lege og en pasient som skal behandles. Implementer de to startTreatment-metodene og treatmentFinished (sistnevnte brukes ikke i denne underoppgaven, men senere).

Expand
titleLF
 

startTreatment(Doctor) finner en pasient å tilordne en doktor (som har kommet på jobb eller er blitt ledig), ved å velge første (om noen) av de som venter på behandling (getWaitingPatients). Finner vi en pasient, settes doktoren sin pasient og true returneres, eller returneres false.

startTreatment(Patient): Denne likner veldig på den første, men er fra en pasient sitt perspektiv. Her tas det utgangspunkt i ledige doktorer (getAvailableDoctors). Finnes ingen ledig doktor returneres false, ellers settes den første doktoren i samlingen til pasienten det er snakk om, og true returneres. Her kan ville det vært en fordel om getAvailableDoctors returnerte en liste, siden vi trenger å ta ut element  på en bestemt indeks (0).

treatmentFinished(Doctor): Vi har valgt å utløse et unntak av type IllegalStateException hvis doktoren ikke har noen til behandling. Koblingen mellom doktor og pasienten fjernes setPatient(null)-kallet. Siden pasientene i del 1 ikke har noen (helse)tilstander slik de får i del 2, er de ferdig behandlet og kan da fjernes fra systemet med patients.remove(patient). Og siden doktoren nå blir ledig, så trigges behandling av en ny pasient med et kall til startTreatment.

 

               private boolean startTreatment(Doctor doctor) { // 1c

                              Collection<Patient> waitingPatients = getWaitingPatients();

                              if (waitingPatients.isEmpty()) {

                                            return false;

                              }

                   doctor.setPatient(waitingPatients.iterator().next());

                              return true;

               }

 

               private boolean startTreatment(Patient patient) { // 1c

                              Collection<Doctor> availableDoctors = getAvailableDoctors();

                              if (availableDoctors.isEmpty()) {

                                            return false;

                              }

                              Doctor doctor = availableDoctors.iterator().next();

                              doctor.setPatient(patient);

                              return true;

               }

 

               public void treatmentFinished(Doctor doctor) { // 1c

                              if (doctor.getPatient() == null) {

                                            throw new IllegalStateException(doctor + " has no patient!");

                              }

                              Patient patient = doctor.getPatient();

                              doctor.setPatient(null);

                              patients.remove(patient);

                              startTreatment(doctor);

               }


...