Egyszerű állapotgépek megvalósítása Java Enums-sel

1. Áttekintés

Ebben az oktatóanyagban áttekintjük az State Machines-t és azt, hogy miként valósíthatók meg a Java-ban az Enums segítségével.

Ezenkívül elmagyarázzuk ennek a megvalósításnak az előnyeit, összehasonlítva az interfészekkel és az egyes államok konkrét osztályával.

2. Java Enums

A Java Enum egy speciális osztálytípus, amely meghatározza az állandók listáját. Ez lehetővé teszi típusbiztonságos megvalósítás és olvashatóbb kód.

Tegyük fel például, hogy van egy HR szoftverrendszerünk, amely jóváhagyhatja az alkalmazottak által benyújtott szabadságkérelmeket. Ezt a kérést a csapatvezető felülvizsgálja, és eljuttatja az osztályvezetőhöz. Az osztályvezető felelős a kérelem jóváhagyásáért.

A legegyszerűbb enum, amely a szabadságkérelem állapotait tartalmazza:

public enum LeaveRequestState {beküldve, eszkalálva, jóváhagyva}

Hivatkozhatunk ennek a leírásnak az állandóira:

LeaveRequestState állapot = LeaveRequestState.Subuted;

Az Enums módszereket is tartalmazhat. Írhatunk egy absztrakt módszert egy enumba, amely minden enum példányt arra kényszerít, hogy ezt a módszert megvalósítsa. Ez nagyon fontos az állami gépek megvalósításához, amint alább láthatjuk.

Mivel a Java felsorolás hallgatólagosan kiterjeszti az osztályt java.lang.Enum, nem terjeszthetnek ki újabb osztályt. Meg tudnak valósítani egy interfészt, csakúgy, mint bármely más osztályt.

Íme egy példa egy absztrakt módszert tartalmazó enumra:

public enum LeaveRequestState {Beküldve {@Orride public String felelős személy () {return "Munkavállaló"; }}, Eszkalálva {@Orride public String felelős személy (() {return "Csapatvezető"; }}, Jóváhagyva {@Orride public String felelős személy (() {return "osztályvezető"; }}; nyilvános absztrakt Karakterlánc felelős személy (); }

Vegye figyelembe a pontosvessző használatát az utolsó enumállandó végén. A pontosvesszőre akkor van szükség, ha egy vagy több módszerünk követi az állandókat.

Ebben az esetben az első példát kibővítettük a-val felelős személy() módszer. Ez megmondja nekünk az egyes műveletek végrehajtásáért felelős személyt. Tehát, ha megpróbáljuk ellenőrizni a felelős személyt Eszkalálódott állapotot, akkor megkapja a „Csapatvezetőt”:

LeaveRequestState állapot = LeaveRequestState.Escalated; assertEquals ("Csapatvezető", state.responsiblePerson ());

Ugyanígy, ha ellenőrizzük, hogy ki felel a kérés jóváhagyásáért, akkor az „osztályvezetőnek” megadja:

LeaveRequestState state = LeaveRequestState.Approved; assertEquals ("Osztályvezető", state.responsiblePerson ());

3. Állami gépek

Az állapotgép - amelyet véges állapotú gépnek vagy véges automatának is nevezünk - egy absztrakt gép felépítésére használt számítási modell. Ezek a gépek csak egy állapotban lehetnek adott időben. Minden állapot a rendszer állapota, amely másik állapotra változik. Ezeket az állapotváltozásokat átmeneteknek nevezzük.

Matematikában diagramokkal és jelölésekkel bonyolultabbá válhat, de nekünk programozóknak sokkal könnyebb a helyzet.

Az State Pattern a GoF egyik jól ismert huszonhárom mintája. Ez a minta kölcsönzi a koncepciót a matematika modelljétől. Lehetővé teszi egy objektum számára, hogy állapota alapján különböző viselkedéseket foglaljon magában ugyanazon objektum esetében. Programozhatjuk az állapotok közötti átmenetet, és később külön állapotokat határozhatunk meg.

A koncepció jobb megmagyarázása érdekében kibővítjük a szabadságkérés példáját egy állami gép megvalósítása érdekében.

4. Enums mint állami gépek

Arra fogunk összpontosítani, hogy az állami gépek Java-ba kerülnek. Más megvalósítások is lehetségesek, ezeket összehasonlítjuk a következő szakaszban.

Az állapotgépi megvalósítás fő kérdése enum segítségével az nem kell az államok kifejezett beállításával foglalkoznunk. Ehelyett csak megadhatjuk a logikát arról, hogyan lehet áttérni az egyik állapotról a másikra. Merüljünk jobbra:

public enum LeaveRequestState {Beküldve {@Orride public LeaveRequestState nextState () {return Escalated; } @Orride public String felelős személy () {return "Alkalmazott"; }}, Eszkalálva {@Override public LeaveRequestState nextState () {return Jóváhagyva; } @Orride public String felelős személy () {return "Csapatvezető"; }}, Jóváhagyott {@Override public LeaveRequestState nextState () {return this; } @Orride public String felelős személy () {return "osztályvezető"; }}; public abstract LeaveRequestState nextState (); nyilvános absztrakt Karakterlánc felelős személy (); }

Ebben a példában a az állapotgép-átmenetek az enum absztrakt módszereivel valósulnak meg. Pontosabban, a nextState () minden enum konstanson megadjuk az átmenetet a következő állapotba. Szükség esetén a előzőState () módszer.

Az alábbiakban bemutatjuk egy tesztet a megvalósításunk ellenőrzésére:

LeaveRequestState állapot = LeaveRequestState.Subuted; állapot = állapot.nextState (); assertEquals (LeaveRequestState.Escalated, állapot); állapot = állapot.nextState (); assertEquals (LeaveRequestState.Approved, állapot); állapot = állapot.nextState (); assertEquals (LeaveRequestState.Approved, állapot);

A szabadság iránti kérelmet a Beküldve kezdeti állapot. Ezután ellenőrizzük az állapotátmeneteket a nextState () a fentiekben megvalósított módszer.

Vegye figyelembe, hogy mivel Jóváhagyott a végső állapot, más átmenet nem történhet.

5. Az állami gépek Java Enums-sel történő megvalósításának előnyei

Az interfészekkel és implementációs osztályokkal rendelkező állapotgépek megvalósítása jelentős mennyiségű kódot jelenthet a fejlesztéshez és fenntartáshoz.

Mivel a Java enum a legegyszerűbb formájában konstansok listája, ezért enum segítségével definiálhatjuk állapotunkat. És mivel egy enum magatartást is tartalmazhat, módszerek segítségével biztosíthatjuk az állapotok közötti átmenet megvalósítását.

Ha az összes logikát egy egyszerű enum tartalmazza, tiszta és egyértelmű megoldást kínálunk.

6. Következtetés

Ebben a cikkben megvizsgáltuk az állami gépeket és azt, hogy miként valósíthatók meg a Java-ban az Enums segítségével. Hoztunk egy példát és teszteltük.

Végül megvitattuk az enumok állami gépek megvalósításának előnyeit is. Az interfész és a megvalósítási megoldás alternatívájaként az enums az állami gépek tisztább és érthetőbb megvalósítását nyújtja.

Mint mindig, a cikkben említett összes kódrészlet megtalálható a GitHub-adattárunkban.