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.