Follow treslines by email clicking Here!

Tuesday, August 12, 2014

Programming Design Pattern - Proxy Pattern Applied - Best Practise

Hi there!

Today i'm gonna show the proxy design pattern in action. The proxy is definitely not as present in our daily work as the other design patterns already presented. But it also has its purpose. Especially when it comes to security, remote accesses or processing heavy weight tasks in background without exposing the real implementation of it.

I'm assuming here you already know the concepts and i'll be focusing on practise. The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it.

First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.

The UML Diagram of the Proxy Pattern


Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.

The Credentials

In the example bellow we will simulate a login access. For this reason let's define the credentials first.

public class Credential {
    private String username;
    private String password;
    public Credential(String username, String password) {
        this.username = username;this.password = password;
    }
    public String getUsername() {return username;}
    public void setUsername(String username) {this.username = username;}
    public String getPassword() {return password;}
    public void setPassword(String password) {this.password = password;}
}
public class SystemCredential {
    private Credential credential;
    private String username;
    private String password;
    public SystemCredential(Credential credential) {
        this.credential=credential;
        // simulating db or whatever access and getting system user info
        this.username = "sysAdmim";
        this.password = "sysPwd";
    }
    public boolean canAccess(){
        final boolean isUsernameOK = username.equals(credential.getUsername());
        final boolean isPasswordOK = password.equals(credential.getPassword());
        boolean sucess = isUsernameOK && isPasswordOK;
        if(sucess){
            // set flag in db or anywhere else (userAccessExpired=false) 
            // and start userAccessCountDown till session expires or user logs off.
        }return sucess;
    }
}

The Access Interface

This is the real access implementation. This is the structure responsible for the login process.

// SUBJECT
public interface Access {
    public boolean access(Credential credential);
    public boolean isExpired(Credential credential);
}
// REAL SUBJECT - DOES THE HEAVY WEIGHTING WORK
public class Login implements Access {
    @Override
    public boolean access(Credential credential) {
         return new SystemCredential(credential).canAccess();
    }
    public boolean isExpired(Credential credential) {
        // simulating db or whatever request to check this...
        final Random random = new Random();
        final int nextInt = random.nextInt(2);
        return nextInt==0?true:false;
    }
}

The Proxy

The proxy sends requests to the real implementation. The user thinks he is dealing with the real implementation while it is not.

// PROXY SENDS REQUESTS TO THE REAL SUBJECT (Login) MAKING ACCESSES EFFECTIVELY
public class LoginProxy implements Access {
    private Access user =  new Login();
    @Override
    public boolean access(Credential credential) {
//        if(!isExpired(credential)){
//            return true;
//        }return user.access(credential);
        return user.access(credential);
    }
    @Override
    public boolean isExpired(Credential credential) {
        return user.isExpired(credential);
    }
}

Testing it

Here we simulate what really happens. The only thing the user knows is the common interface Access.

public class Client {
    public static void main(String[] args) {
        Access login =  new LoginProxy();
        final Credential wrongCredential = new Credential("username", "password");
        final Credential rightCredential = new Credential("sysAdmim", "sysPwd");
        loginStatus(login, wrongCredential);
        loginStatus(login, rightCredential);
    }
    private static void loginStatus(Access login, final Credential credential) {
        boolean access = login.access(credential);
        if(access){System.out.println("Logget In: true");}
        else{System.out.println("Logged In: false");}
    }
}

That's all! Hope you like it!

No comments:

Post a Comment