Implementacija jednostavnih državnih strojeva s Java Enumovima

1. Pregled

U ovom uputstvu ćemo pogledati State Machines i kako se oni mogu implementirati u Javi pomoću Enumsa.

Također ćemo objasniti prednosti ove implementacije u usporedbi s upotrebom sučelja i konkretne klase za svaku državu.

2. Java Enums

Java Enum je posebna vrsta klase koja definira popis konstanti. To omogućuje sigurna implementacija i čitljiviji kod.

Kao primjer, pretpostavimo da imamo HR softverski sustav koji može odobriti zahtjeve za dopustom koje su podnijeli zaposlenici. Ovaj zahtjev pregledava vođa tima koji ga prosljeđuje upravitelju odjela. Voditelj odjela je osoba odgovorna za odobravanje zahtjeva.

Najjednostavniji popis koji sadrži stanja zahtjeva za dopustom je:

public enum LeaveRequestState {Podneseno, eskalirano, odobreno}

Možemo se pozvati na konstante ovog nabrajanja:

LeaveRequestState state = LeaveRequestState.Submitted;

Enumi također mogu sadržavati metode. U enum možemo napisati apstraktnu metodu koja će prisiliti svaku instancu nabrajanja da primijeni ovu metodu. To je vrlo važno za implementaciju državnih strojeva, kao što ćemo vidjeti u nastavku.

Budući da Java nabraja implicitno proširuje klasu java.lang.Enum, ne mogu produžiti još jedan razred. Međutim, oni mogu implementirati sučelje, baš kao i bilo koja druga klasa.

Evo primjera nabrajanja koji sadrži apstraktnu metodu:

public enum LeaveRequestState {Submitted {@Override public String адказнаPerson () {return "Zaposlenik"; }}, Escalated {@Override public String loadedPerson () {return "Vođa tima"; }}, Odobreno {@Override public String loadedPerson () {return "Voditelj odjela"; }}; javni sažetak Niz odgovorniPerson (); }

Primijetite upotrebu točke sa zarezom na kraju posljednje konstante nabrajanja. Zarez je potreban kad imamo jednu ili više metoda koje slijede konstante.

U ovom smo slučaju prvi primjer proširili s odgovorna osoba() metoda. To nam govori osoba odgovorna za izvođenje svake radnje. Dakle, ako pokušamo provjeriti osobu odgovornu za Eskalirano država, dat će nam "Vođa tima":

LeaveRequestState state = LeaveRequestState.Escalated; assertEquals ("Vođa tima", state.responsiblePerson ());

Na isti način, ako provjerimo tko je odgovoran za odobravanje zahtjeva, dat će nam “Voditelja odjela”:

LeaveRequestState state = LeaveRequestState.Approved; assertEquals ("Voditelj odjela", state.responsiblePerson ());

3. Državni strojevi

Državni stroj - koji se naziva i konačnim automatom ili konačnim automatom - računski je model koji se koristi za izgradnju apstraktnog stroja. Ovi strojevi mogu biti u određenom trenutku samo u jednom stanju. Svaka država je status sustava koji se mijenja u drugo stanje. Te se promjene stanja nazivaju prijelazima.

Može se zakomplicirati u matematici dijagramima i notacijama, ali nama programerima stvari stoje puno lakše.

Državni obrazac jedan je od poznatih dvadeset i tri dizajnerska uzorka GoF-a. Ovaj obrazac posuđuje koncept iz modela u matematici. Omogućuje objektu da enkapsulira različita ponašanja za isti objekt, na temelju njegovog stanja. Možemo programirati prijelaz između država i kasnije definirati odvojena stanja.

Da bismo bolje objasnili koncept, proširit ćemo naš primjer zahtjeva za napuštanje kako bismo implementirali državni stroj.

4. Enumi kao državni strojevi

Usredotočit ćemo se na enum implementaciju državnih strojeva u Javi. Moguće su i druge implementacije, a mi ćemo ih usporediti u sljedećem odjeljku.

Glavna poanta implementacije državnog stroja pomoću enum-a je ta ne moramo se baviti eksplicitnim postavljanjem stanja. Umjesto toga, možemo samo pružiti logiku kako prijeći iz jednog stanja u sljedeće. Uronimo pravo u:

public enum LeaveRequestState {Submitted {@Override public LeaveRequestState nextState () {return Escalated; } @Override public String loadedPerson () {return "Zaposlenik"; }}, Eskalirano {@Override public LeaveRequestState nextState () {return Odobreno; } @Override public String loadedPerson () {return "Vođa tima"; }}, Odobreno {@Override public LeaveRequestState nextState () {return this; } @Override public String loadedPerson () {return "Voditelj odjela"; }}; javni sažetak LeaveRequestState nextState (); javni sažetak Niz odgovorniPerson (); }

U ovom primjeru, prijelazi državnih strojeva provode se pomoću apstraktnih metoda popisa. Točnije, pomoću nextState () na svakoj enum konstanti određujemo prijelaz u sljedeće stanje. Ako je potrebno, možemo implementirati i previousState () metoda.

Ispod je test za provjeru naše implementacije:

LeaveRequestState state = LeaveRequestState.Submitted; stanje = stanje.nextState (); assertEquals (LeaveRequestState.Escalated, stanje); stanje = stanje.nextState (); assertEquals (LeaveRequestState.Approved, stanje); stanje = stanje.nextState (); assertEquals (LeaveRequestState.Approved, stanje);

Zahtjev za dopustom započinjemo u Podneseno početno stanje. Zatim provjeravamo prijelaze stanja pomoću nextState () metodu koju smo gore primijenili.

Imajte na umu da od Odobreno je konačno stanje, ne može se dogoditi nikakav drugi prijelaz.

5. Prednosti primjene državnih strojeva s Java Enumovima

Implementacija državnih strojeva s sučeljima i klasama implementacije može biti značajna količina koda za razvoj i održavanje.

Budući da je Java enum u svom najjednostavnijem obliku popis konstanti, enum možemo koristiti za definiranje naših stanja. A budući da enum može sadržavati i ponašanje, možemo koristiti metode kako bismo osigurali provedbu prijelaza između stanja.

Imati svu logiku u jednostavnom nabrajanju omogućuje čisto i jednostavno rješenje.

6. Zaključak

U ovom smo članku pogledali državne strojeve i kako se oni mogu implementirati u Javu pomoću Enumsa. Dali smo primjer i testirali ga.

Na kraju smo razgovarali i o prednostima korištenja enuma za implementaciju državnih strojeva. Kao alternativa rješenju sučelja i implementacije, enumi pružaju čišću i lakše razumljivu implementaciju državnih strojeva.

Kao i uvijek, svi isječci koda spomenuti u ovom članku mogu se naći u našem GitHub spremištu.