PROXY PATTERN

The Proxy Pattern provides a surrogate or placeholder for another object to control access to it.

The Proxy Pattern is used to create a representative object that controls access to another object, which may be remote, expensive to create or in need of being secured.

One reason for controlling access to an object is to defer the full cost of its creation and initialization until we actually need to use it. Another reason could be to act as a local representative for an object that lives in a different JVM. The Proxy can be very useful in controlling the access to the original object, especially when objects should have different access rights.

In the Proxy Pattern, a client does not directly talk to the original object, it delegates it calls to the proxy object which calls the methods of the original object. The important point is that the client does not know about the proxy, the proxy acts as an original object for the client. But there are many variations to this approach which we will see soon.

There are three main variations to the Proxy Pattern:

  • A remote proxy provides a local representative for an object in a different address space.
  • A virtual proxy creates expensive objects on demand.
  • A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights.

IFolder.java

package com.myjavablog.structural.proxy;

public interface IFolder {

public void performOperations();
}

Folder.java

package com.myjavablog.structural.proxy;

public class Folder implements IFolder {

@Override
public void performOperations() {
//Access folder and perform various operations like copy or cut
System.out.println("Performing operation on folder");
}
}

User.java

package com.myjavablog.structural.proxy;

public class User {

String userName;
String password;

public User(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;
}
}

FolderProxy.java

package com.myjavablog.structural.proxy;

public class FolderProxy implements IFolder {

Folder folder;
User user;

public FolderProxy(User user){
this.user = user;
}

@Override
public void performOperations() {

if(user.getUserName().equalsIgnoreCase("test")
&& user.getPassword().equalsIgnoreCase("test")){
folder=new Folder();
folder.performOperations();
}else{
System.out.println("You don't have access to this folder");
}
}
}

ProxyPatternTest.java

package com.myjavablog.structural.proxy;

public class ProxyPatternTest {

public static void main(String[] args) {

User user = new User("test", "test");
FolderProxy folderProxy = new FolderProxy(user);
System.out.println("When username and password are correct");
folderProxy.performOperations();
System.out.println("========================================");
User userWrong = new User("abc", "abc");
FolderProxy folderProxyWrong = new FolderProxy(userWrong);
System.out.println("When username and password are incorrect");
folderProxyWrong.performOperations();

}
}

 

Output:

When username and password are correct
Performing operation on folder
========================================
When username and password are incorrect
You don't have access to this folder

 

When to use the Proxy Pattern:

Proxy is applicable whenever there is a need for a more versatile or sophisticated reference to an object than a simple pointer. Here are several common situations in which the Proxy pattern is applicable:

  • A remote proxy provides a local representative for an object in a different address space.
  • A virtual proxy creates expensive objects on demand.
  • A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights.

Proxy Pattern in JDK:

The following cases are examples of usage of the Proxy Pattern in the JDK.

  • java.lang.reflect.Proxy
  • java.rmi. (whole package)
Bitnami