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

  1. Utworzyć Smoka, który może przyjmować określone stany i może
    pobierać i wydatkować energię.
  2. Utworzyć klasę Stan dla konkretnego Smoka zawierającą ogólne metody
    dodawania i wydatkowania kalorii.
  3. 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.
  4. 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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *