Java design pattern: Proxy

Today we will take a look at another Java design pattern from the structural patterns category – Proxy. Design patterns in this category deal with class structure such as inheritance and composition.

What is the Proxy design pattern?

The Proxy pattern is a design pattern that allows you to control access to an object by making it available through another object (a proxy) and provide additional functionality such as access rights authentication, access logging, delayed creation of challenging objects, and more. This pattern belongs to the group of structural patterns because it deals with how objects are composed into larger structures.

What problem does the Proxy design pattern solve?

The proxy effectively solves cases where we want to have control over access to an object. For example, if we are working with an object with sensitive data that we would like to let the application access only in certain situations, or if we need to know which clients have accessed the object and when. The proxy gives us the ability to handle such situations without direct access to the main object. For the client, using a proxy object is similar to using a real object because they both implement the same interface, although in reality the proxy is awrapper class of the real object.

Example of Proxy implementation in Java

We will now implement a program that demonstrates the use of the Proxy design pattern in Java when logging into an information system. The program also checks access rights and logs access.

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);
}

The Pristup interface defines an vykonajOperaciu method common to 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);
    }
}

The RealnyPristup class, implements the Pristup interface. Represents a real object that also performs a real operation for the client with the given 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());
    }
}

The ProxyPristup class implements the Pristup interface. Represents a proxy object that controls access rights based on a username and password. It also logs the access and, if the access data is correct, delegates the call of the vykonajOperaciu method to the real object 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);
    }
}

An instance of the ProxyPristup class is created in the main method and we test how our implementation checks and logs client accesses.

The program prints access and access denial messages based on the access data entered. If the credentials match the expected values (username “admin” and password “password123”), the Proxy will allow access to the real object and execute its operation. The access time is also logged.

The output of this example is:

An instance of the ProxyPristup class is created in the main method

Summary

The Proxy design pattern is often used in situations where we need to provide access control and first verify the correctness of the data and/or check the permissions to use the methods before calling the methods on the real object.

We have prepared the files with the above example in the form of code that you can run directly in Java. Download the Java Proxy code here.

Do you know the Java programming language? If you’re looking for a job as a Java developer, check out our employee benefits and respond to our latest job offers.

About the author

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.

Let us know about you