Proxy Design Pattern In java

Type : Structural Design Pattern

Summary


Proxy Design pattern lets a Proxy Object rather then the real object to interact with Client. By doing so the proxy can control access to the real object or delay the creation of real object unless it is is really needed.

Description


In Proxy Design pattern the Client is served with a Proxy Object rather than the real object. Benefit of doing so is that, we have greater control in when to create the real object. It would help us in providing in lazy loading the real object, providing extra security checking etc. 

Example


For example lets consider a service called UserDetails Service which the Client calls to get UserDetails Object. Now say UserDetails is a complex object, and we need to real the database to populate it. Also we would like to have a security authorization check by which we will not show the details at all or show only few attributes from UserDetails Object.

Returning a Proxy rather than original object help us in achieving our goals. In our example UserDetailsProxy either returns a proxy object or real object based on the parameter(caller id). Say if "admin" user is calling than it returns the actual object otherwise it returns the proxy object.

Class Diagram




Sample Code


public interface UserDetails {

  public UserDetails getUserDetails(String callerId, String uid);

  public Double getTotalBalance(String uid);
}

// actual Object which contains UserDetails
public class UserDetailsImpl implements UserDetails {

  private String userId;
  private String bankAccountNo;
  private String socialSecurityNo;
  private String zipCode;
  private Double totalBalance;

  @Override
  public UserDetails getUserDetails(String callerId, String uid) {
    return UserDetailsService.retrieveUserById(uid);
  }

  public UserDetailsImpl() {

  }

  @Override
  public String toString() {
    return "userId=" + this.userId + " bankAccountNo=" + this.bankAccountNo + " socialsecurity="
        + socialSecurityNo;
  }

  @Override
  public Double getTotalBalance(String uid) {
    return totalBalance;
  }

}


// proxy Object for UserDetails
public class UserDetailsProxy implements UserDetails {

  UserDetailsImpl realUserDetails = null;

  @Override
  public UserDetails getUserDetails(String callerId, String uId) {
    if (callerId.equalsIgnoreCase("admin")) {
      return UserDetailsService.retrieveUserById(uId);
    } else {
      return new UserDetailsProxy();
    }
  }


  @Override
  public String toString() {
    return "userId=NA bankAccountNo=NA socialsecurity=NA";
  }


  @Override
  public Double getTotalBalance(String uid) {
    if (realUserDetails == null) {
      realUserDetails = UserDetailsService.retrieveUserById(uid);
    }

    return realUserDetails.getTotalBalance();
  }

}


//UserDetails Service which returns the Object
public class UserDetailsService {

  public static UserDetailsImpl retrieveUserById(String uId) {
    UserDetailsImpl userDetail = new UserDetailsImpl();
    userDetail.setUserId(uId);
    userDetail.setBankAccountNo("swissbank_11228899");
    userDetail.setSocialSecurityNo("888 11 777");
    userDetail.setZipCode("95011");
    userDetail.setTotalBalance(99.9);
    return userDetail;
  }
}

Github Code

Advantages


Proxies can help increase performance by delaying creation of the real object.
It can improve security by wrapping the real object by proxy object and returning real object when allowed.

Disadvantages

Proxy pattern introduces new Proxy objects.
Proxy objects might need to refactored if the Original object also changes.

References

https://en.wikipedia.org/wiki/Proxy_pattern

Comments

Popular posts from this blog

Difference between volatile and synchronized

Converting Java Map to String

Masking Credit Card number in Java