Návrhové vzory Java (design patterns): Proxy

Dnes sa pozrieme na ďalší návrhový vzor Proxy (java design patterns) z kategórie štrukturálnych vzorov (structural patterns). Návrhové vzory v tejto kategórii sa zaoberajú štruktúrou triedy, ako je dedičnosť (inheritance) a kompozícia (composition).

Čo je návrhový vzor Proxy?

Vzor Proxy je návrhový vzor, ktorý umožňuje kontrolovať prístup k objektu jeho sprístupnením cez iný objekt (proxy) a poskytnúť dodatočnú funkcionalitu, ako sú napríklad overovanie prístupových práv, logovanie prístupov, oneskorené vytváranie náročných objektov a ďalšie. Tento vzor patrí do skupiny štrukturálnych vzorov, pretože sa zaoberá tým, ako sú objekty komponované do väčších štruktúr.

Aký problém návrhový vzor Proxy rieši?

Proxy rieši efektívne prípady, keď chceme mať kontrolu nad prístupom k objektu. Napríklad, ak pracujeme s objektom s citlivými dátami, na ktorý by sme chceli nechať aplikáciu pristupovať len v určitých situáciách, alebo ak potrebujeme vedieť, ktorí klienti a kedy k danému objektu pristupovali. Proxy nám dáva možnosť riešiť takéto situácie bez priameho prístupu k hlavnému objektu. Pre klienta je použitie proxy objektu podobné používaniu skutočného objektu, pretože oba implementujú rovnaké rozhranie, aj keď v skutočnosti proxy je obalová trieda (wrapper) skutočného objektu.

Príklad Proxy implementácie v Jave

Teraz si implementujeme program, ktorý demonštruje použitie návrhového vzoru Proxy v jazyku Java pri prihlasovaní sa do informačného systému. Program tiež kontroluje prístupové práva a loguje prístup.

Pristup.java

package designpatterns;

// Rozhranie definujúce spoločné metódy pre RealnyPristup a ProxyPristup.
public interface Pristup {
    void vykonajOperaciu(String meno, String heslo, int idKlienta);
}

Rozhranie Pristup definuje metódu vykonajOperaciu spoločnú pre RealnyPristup a ProxyPristup.

RealnyPristup.java

package designpatterns;

// RealnyPristup - skutočný objekt, ktorý implementuje rozhranie Pristup.
public class RealnyPristup implements Pristup {
    public void vykonajOperaciu(String meno, String heslo, int idKlienta) {
        System.out.println("Vykonávam operáciu pre klienta s ID: " + idKlienta);
    }
}

Trieda RealnyPristup, implementuje rozhranie Pristup. Predstavuje skutočný objekt, ktorý aj reálne vykonáva operáciu pre klienta s daným ID.

ProxyPristup.java

package designpatterns;

import java.util.Date;

public class ProxyPristup  implements Pristup {
    private RealnyPristup realnyPristup;

    public void vykonajOperaciu(String meno, String heslo, int idKlienta) {
        logujPristup(idKlienta);
        if (skontrolujPristupovePrava(meno, heslo)) {
            if (realnyPristup == null) {
                realnyPristup = new RealnyPristup();
                System.out.println("Prístup bol povolený.");
            }
            realnyPristup.vykonajOperaciu(meno, heslo, idKlienta);
        } else {
            System.out.println("Nesprávne prístupové údaje. Prístup bol zamietnutý!");
        }
    }

    private boolean skontrolujPristupovePrava(String meno, String heslo) {
        // Simulácia kontrolu prístupových práv, môžete pridať vlastnú logiku
        return "admin".equals(meno) && "heslo123".equals(heslo);
    }

    private void logujPristup(int idKlienta) {
        // Simulácia logovania prístupu
        System.out.println("Pristup klienta s ID [" + idKlienta + "] do systému o " + new Date());
    }
}

Trieda ProxyPristup, implementuje rozhranie Pristup. Predstavuje proxy objekt, ktorý kontroluje prístupové práva na základe mena a hesla. Zároveň loguje prístup a ak sú prístupové údaje správne, deleguje zavolanie metódy vykonajOperaciu na reálnom objekte RealnyPristup.

Main.java

import designpatterns.Pristup;
import designpatterns.ProxyPristup;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // Použitie Proxy
        Pristup proxy = new ProxyPristup();
        proxy.vykonajOperaciu("jwagner", "heslo123", 823);
        System.out.println();
        Thread.sleep(800);
        proxy.vykonajOperaciu("admin", "heslo1234", 111);
        System.out.println();
        Thread.sleep(700);
        proxy.vykonajOperaciu("admin", "heslo123", 111);
    }
}

V main metóde je vytvorená inštancia triedy ProxyPristup a testujeme ako naša implementácia kontroluje a loguje prístupy klientov.

Program vypíše správy o prístupoch a zamietnutiach prístupu na základe zadaných prístupových údajov. Ak sa prístupové údaje zhodujú s očakávanými hodnotami (meno „admin“ a heslo „heslo123“), Proxy umožní prístup k reálnemu objektu a vykoná jeho operáciu. Čas prístupu sa taktiež loguje.

Výstup z tohto príkladu je:

V main metóde je vytvorená inštancia triedy ProxyPristup

Zhrnutie

Návrhový vzor Proxy sa často používa v situácii, keď potrebujeme zabezpečiť riadenie prístupu a pred zavolaním metód na reálnom objekte najskôr verifikovať správnosť údajov a/alebo kontrolovať oprávnenia dané metódy používať.

Pripravili sme pre teba súbory so spomínaným príkladom vo forme kódu, ktorý si môžeš spustiť priamo v Jave. Stiahni si kód Java Proxy tu.

Ovládaš programovací jazyk Java? Ak hľadáš prácu ako Java programátor, pozri si naše firemné benefity a reaguj na najnovšie pracovné ponuky.

O autorovi

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Daj nám o sebe vedieť