Wzorzec projektowy State
Zadanie Programistyczne
Smoki leżące w szpitalu muszą być monitorowane co do stanów odżywienia.
Stanów jest trzy.
Rozwiązanie
- Utworzyć Smoka, który może przyjmować określone stany i może
pobierać i wydatkować energię. - Utworzyć klasę Stan dla konkretnego Smoka zawierającą ogólne metody
dodawania i wydatkowania kalorii. - Utworzyć trzy klasy po jednej dla każdego stanu. Klasy dziedziczą po klasie Stan.
Należy nadpisać metody dotyczące pobierania i wydatkowania energii. Należy uwzględnić zmianę stanu Smoka, o ile zachodzi taka zmiana. - Uruchomić i sprawdzić działanie.
Klasy
Klasa Smok
package state; class Smok { public static final double MAX_STAN_KALORII = 60000.0; public static final double MIN_STAN_KALORII = 30000.0; public static final String ERROR = "Error: Koniec zapasu energii"; public static final String ERROR_UP = "Error: Koniec jedzenia. " + "Stan zagrażający życiu"; private Stan stanPacjenta; private final String nrLozka; private double stanOdzywienia; public Smok(String nrLozka) { this.nrLozka = nrLozka; stanPacjenta = Stan.stanPoczatkowy(this); } public void setState(Stan stanPacjenta) { this.stanPacjenta = stanPacjenta; } private Stan getStanPacjenta() { return stanPacjenta; } public String getNrLozka() { return nrLozka; } public boolean dodajKalorie(double liczbaKalorii) { return getStanPacjenta().dodajKalorie(liczbaKalorii); } public boolean wydatkujKalorie(double liczbaKalorii) { return getStanPacjenta().wydatkujKalorie(liczbaKalorii); } public double getStanOdzywienia() { return stanOdzywienia; } public void setStanOdzywienia(double stanOdzywienia) { this.stanOdzywienia = stanOdzywienia; } }
Klasa Stan
package state; public class Stan { private Smok smok; Stan(Smok smok) { this.smok = smok; } Stan(Stan stan) { this.smok = stan.getSmok(); } Smok getSmok() { return smok; } public void setSmok(Smok smok) { this.smok = smok; } public static Stan stanPoczatkowy(Smok smok) { return new StanAktywnosci(smok); } public boolean dodajKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() + liczbaKalorii; getSmok().setStanOdzywienia(bilansKalorii); System.out.println("Smok pobrał " + liczbaKalorii + " kalorii "); return true; } public boolean wydatkujKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() - liczbaKalorii; getSmok().setStanOdzywienia(bilansKalorii); System.out.println("Smok wydatkował " + liczbaKalorii + " kalorii "); return true; } @Override public String toString() { return this.getClass().getSimpleName(); } }
Klasa StanAktywnosci
package state; public class StanAktywnosci extends Stan { public StanAktywnosci(Smok smok) { super(smok); } public StanAktywnosci(Stan stan) { super(stan); System.out.println("stan aktywności"); } @Override public boolean dodajKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() + liczbaKalorii; if (bilansKalorii > Smok.MAX_STAN_KALORII) { getSmok().setState(new StanPrzekarmienia(this)); } return super.dodajKalorie(liczbaKalorii); } @Override public boolean wydatkujKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() - liczbaKalorii; if ((bilansKalorii) >= Smok.MIN_STAN_KALORII) { super.wydatkujKalorie(liczbaKalorii); return true; } else if ((bilansKalorii) < Smok.MIN_STAN_KALORII) { getSmok().setState(new StanNiedozywienia(this)); super.wydatkujKalorie(liczbaKalorii); return true; } else { System.out.println(Smok.ERROR); return false; } } }
Klasa StanNiedozywienia
package state; public class StanNiedozywienia extends Stan { public StanNiedozywienia(Smok smok) { super(smok); } public StanNiedozywienia(Stan stan) { super(stan); System.out.println("stan niedożywienia"); } @Override public boolean dodajKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() + liczbaKalorii; if (bilansKalorii < Smok.MIN_STAN_KALORII) { return super.dodajKalorie(liczbaKalorii); } else if ((bilansKalorii > Smok.MIN_STAN_KALORII) && (bilansKalorii <= Smok.MAX_STAN_KALORII)) { getSmok().setState(new StanAktywnosci(this)); return super.dodajKalorie(liczbaKalorii); } else if (bilansKalorii > Smok.MAX_STAN_KALORII) { getSmok().setState(new StanPrzekarmienia(this)); return super.dodajKalorie(liczbaKalorii); } else { return false; } } @Override public boolean wydatkujKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() - liczbaKalorii; if ((bilansKalorii) >= Smok.MIN_STAN_KALORII) { return super.wydatkujKalorie(liczbaKalorii); } else { System.out.println(Smok.ERROR); return false; } } }
Klasa StanPrzekarmienia
package state; public class StanPrzekarmienia extends Stan { public StanPrzekarmienia(Smok smok) { super(smok); } public StanPrzekarmienia(Stan stan) { super(stan); System.out.println("stan przekarmienia"); } @Override public boolean dodajKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() + liczbaKalorii; if (bilansKalorii <= Smok.MAX_STAN_KALORII) { return super.dodajKalorie(liczbaKalorii); } else { System.out.println(Smok.ERROR_UP); return false; } } @Override public boolean wydatkujKalorie(double liczbaKalorii) { double bilansKalorii = getSmok().getStanOdzywienia() - liczbaKalorii; if (bilansKalorii > Smok.MAX_STAN_KALORII) { return super.wydatkujKalorie(liczbaKalorii); } else if ((bilansKalorii >= Smok.MIN_STAN_KALORII) && (bilansKalorii < Smok.MAX_STAN_KALORII)) { getSmok().setState(new StanAktywnosci(this)); return super.wydatkujKalorie(liczbaKalorii); } else { getSmok().setState(new StanNiedozywienia(this)); return super.wydatkujKalorie(liczbaKalorii); } } }
Klasa Main
package state; class Main { public static void main(String[] args) { Smok smok = new Smok("45"); smok.dodajKalorie(20000); smok.dodajKalorie(20000); smok.dodajKalorie(20000); smok.dodajKalorie(20000); smok.dodajKalorie(20000); smok.wydatkujKalorie(30000); smok.wydatkujKalorie(30000); } }
Wynik
Smok pobrał 20000.0 kalorii Smok pobrał 20000.0 kalorii Smok pobrał 20000.0 kalorii stan przekarmienia Smok pobrał 20000.0 kalorii Error: Koniec jedzenia. Stan zagrażający życiu stan aktywności Smok wydatkował 30000.0 kalorii stan niedożywienia Smok wydatkował 30000.0 kalorii