A felelősséglánc tervezési mintája a Java-ban

1. Bemutatkozás

Ebben a cikkben megnézzük a széles körben használtakat viselkedési tervezési minta: A felelősség láncolata.

További tervezési mintákat előző cikkünkben találhatunk.

2. A felelősség láncolata

A Wikipedia a felelősségláncot mint tervezési mintát határozza meg, amely „parancsobjektumok forrásából és objektumok sorozatából áll”.

A lánc minden egyes feldolgozási objektuma felelős egy bizonyos típusú parancsért, és a feldolgozás megtörtént, továbbítja a parancsot a lánc következő processzorának.

A felelősséglánc minta hasznos:

  • A parancs feladójának és vevőjének leválasztása
  • Feldolgozási stratégia kiválasztása a feldolgozás idején

Lássunk tehát egy egyszerű példát a mintára.

3. Példa

A felelősség láncát felhasználva létrehozunk egy láncot a hitelesítési kérelmek kezeléséhez.

Tehát a bemeneti hitelesítés szolgáltatója lesz a parancs, és minden hitelesítési processzor külön lesz processzor tárgy.

Készítsünk először egy absztrakt alaposztályt a processzorok számára:

public abstract class AuthenticationProcessor {public AuthenticationProcessor nextProcessor; // standard konstruktorok public abstract logikai isAuthorized (AuthenticationProvider authProvider); }

Ezután hozzunk létre konkrét processzorokat, amelyek meghosszabbodnak AuthenticationProcessor:

public class OAuthProcessor kiterjeszti az AuthenticationProcessor {public OAuthProcessor (AuthenticationProcessor nextProcessor) {super (nextProcessor); } @ A nyilvános logikai érték felülírása isAuthorized (AuthenticationProvider authProvider) {if (OAuthTokenProvider authProvider instance) {return true; } else if (nextProcessor! = null) {return nextProcessor.isAuthorized (authProvider); } return false; }}
public class UsernamePasswordProcessor kiterjeszti az AuthenticationProcessor {public UsernamePasswordProcessor (AuthenticationProcessor nextProcessor) {super (nextProcessor); } @Orride public boolean isAuthorized (AuthenticationProvider authProvider) {if (authPovider instanceof UsernamePasswordProvider) {return true; } else if (nextProcessor! = null) {return nextProcessor.isAuthorized (authProvider); } return false; }}

Itt két konkrét processzort hoztunk létre bejövő engedélyezési kérelmeinkhez: FelhasználónévPasswordProcessor és OAuthProcessor.

Mindegyiknél felülírjuk a engedélyezett módszer.

Készítsünk néhány tesztet:

public class ChainOfResponsibilityTest {private static AuthenticationProcessor getChainOfAuthProcessor () {AuthenticationProcessor oAuthProcessor = new OAuthProcessor (null); return new FelhasználónévPasswordProcessor (oAuthProcessor); } @Test public void givenOAuthProvider_whenCheckingAuthorized_thenSuccess () {AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor (); assertTrue (authProcessorChain.isAuthorized (új OAuthTokenProvider ())); } @Test public void givenSamlProvider_whenCheckingAuthorized_thenSuccess () {AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor (); assertFalse (authProcessorChain.isAuthorized (új SamlTokenProvider ())); }}

A fenti példa létrehozza a hitelesítési processzorok láncolatát: FelhasználónévPasswordProcessor -> OAuthProcessor. Az első tesztben az engedélyezés sikeres, a másikban meghiúsul.

Első, FelhasználónévPasswordProcessor ellenőrzi, hogy a hitelesítés-szolgáltató-e FelhasználónévPasswordProvider.

Nem ez volt a várható input, FelhasználónévPasswordProcessor küldöttek a OAuthProcessor.

Utoljára a OAuthProcessor feldolgozza a parancsot. Az első teszten mérkőzés van, és a teszt sikeres. A másodikban nincs több processzor a láncban, és ennek eredményeként a teszt kudarcot vall.

4. Végrehajtási alapelvek

Néhány fontos alapelvet szem előtt kell tartanunk a felelősséglánc megvalósítása során:

  • A lánc minden processzorának megvan a megvalósítása a parancs feldolgozásához
    • A fenti példánkban az összes processzor megvalósítja is engedélyezett
  • A lánc minden processzorának hivatkoznia kell a következő processzorra
    • Felett, FelhasználónévPasswordProcessor küldöttek a OAuthProcessor
  • Minden processzor felelős a következő processzorért történő delegálásért, ezért vigyázzon az elvetett parancsokra
    • Ismét a példánkban, ha a parancs a SamlProvider akkor előfordulhat, hogy a kérelem nem kerül feldolgozásra, és jogosulatlan lesz
  • A processzoroknak nem szabad rekurzív ciklust alkotniuk
    • Példánkban nincs ciklus a láncunkban: FelhasználónévPasswordProcessor -> OAuthProcessor. De, ha kifejezetten meghatározzuk FelhasználónévPasswordProcessor mint a következő processzora OAuthProcessor, aztán egy ciklusra jutunk a láncunkban: UsernamePasswordProcessor -> OAuthProcessor -> UsernamePasswordProcessor. Ebben segíthet a következő processzor felvétele a konstruktorban
  • A láncban csak egy processzor kezeli az adott parancsot
    • Példánkban, ha egy bejövő parancs tartalmaz egy példányt OAuthTokenProvider, akkor csak OAuthProcessor kezeli a parancsot

5. Használat a való világban

A Java világban mindennap profitálunk a felelősség láncából. Ilyen klasszikus példa a Servlet Filters in Jáva amelyek lehetővé teszik több szűrő számára a HTTP-kérés feldolgozását. Bár ebben az esetben minden szűrő a következő szűrő helyett a láncot hívja meg.

Vessünk egy pillantást az alábbi kódrészletre, hogy jobban megértsük ezt a mintát a Servlet szűrőkben:

public class CustomFilter implementálja a Filter {public void doFilter (ServletRequest kérés, ServletResponse válasz, FilterChain lánc) dobja az IOException, ServletException {// feldolgozza a kérést // továbbítja a kérést (azaz a parancsot) a filterlánc mentén. doFilter (kérés, válasz ); }}

Amint a fenti kódrészletből látható, meg kell hívnunk FilterChain’S doFilter metódus annak érdekében, hogy a kérést továbbítsák a lánc következő processzorának.

6. Hátrányok

És most, hogy láttuk, mennyire érdekes a felelősséglánc, ne feledjük, néhány hátránya van:

  • Leginkább könnyen eltörhet:
    • ha egy processzor nem tudja felhívni a következő processzort, a parancs eldől
    • ha egy processzor rossz processzort hív, az ciklushoz vezethet
  • Mély verem nyomokat hozhat létre, amelyek befolyásolhatják a teljesítményt
  • Ez duplikált kódhoz vezethet a processzorokon, növelve a karbantartást

7. Következtetés

Ebben a cikkben a felelősség láncáról és annak erősségeiről és gyengeségeiről beszéltünk a bejövő hitelesítési kérelmek hitelesítésére szolgáló lánc segítségével.

És mint mindig, a forráskód megtalálható a GitHubon.