Skip to content

Proxy design pattern #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added 4_2-Proxy Design Pattern class diagram.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 4_2_proxy_pattern_sequence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
# DesignPatternsJava9
This repo consists Gang of Four Design patterns code on Java 9. Each branch in the repository has code of 1 design pattern. Switch repository to try out different design patterns.
# What is Proxy Design Pattern
* Proxy means ‘on behalf of’ or 'representing’ or ‘in place of’ are literal meanings of proxy and that directly explains Proxy Design Pattern.
* A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes.

## Diagram
![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/proxy-pattern/diagrams/4_2-Proxy%20Design%20Pattern%20class%20diagram.jpeg "Diagram")

![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/proxy-pattern/diagrams/4_2_proxy_pattern_sequence.png "Diagram")


### When to use Proxy Design Pattern (Problem statement / Candidate application)
* When creation of object is expensive or heavy weight, which means, when a deep object graph is required in the object creation process, then a high weigh proxy objects
* With basic required fields is created and used until the actual object is not required.

### Learn Design Patterns with Java by Aseem Jain
This repository contains working project code used in video Course by Packt Publication with title "Learn Design Patterns with Java " authored by "Aseem Jain".

### Course link:
https://www.packtpub.com/application-development/learn-design-patterns-java-9-video

### ![ http://in.linkedin.com/in/premaseem](https://github.com/premaseem/DesignPatternsJava9/blob/master/linkedin.png "http://in.linkedin.com/in/premaseem") Profile: http://in.linkedin.com/in/premaseem

### Authors blog on design patterns:
https://premaseem.wordpress.com/category/computers/design-patterns/

### Software Design pattern community face book page:
https://www.facebook.com/DesignPatternGuru/

### Note:
* This code base will work on Java 9 and above versions.
* `diagrams` folders carry UML diagrams.
* `pattern` folder has code of primary example.
* `patternBonus` folder has code of secondary or bonus example.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added diagrams/4_2_proxy_pattern_sequence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 20 additions & 2 deletions pattern/src/com/premaseem/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,28 @@
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
@copyright: 2018 Packt Publication
*/
public class Client {
public static void main (String[] args) {
System.out.println("Singleton cook example ");
System.out.println("Proxy iPhone example");

// Programming against interface
IPhone iPhone;

// Loading proxy iPhone for selection purpose
iPhone = new ProxyiPhone();
phoneOperation(iPhone);

iPhone = new RealiPhone();
phoneOperation(iPhone);

}

public static void phoneOperation(IPhone iPhone){
System.out.println();
System.out.println("### Operations running on - "+ iPhone.getClass().getSimpleName());
iPhone.getColor();
iPhone.getDimension();
iPhone.operateDisplay();
}
}
14 changes: 14 additions & 0 deletions pattern/src/com/premaseem/IPhone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.premaseem;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
*/
public interface IPhone {

void getColor();
void getDimension();
void operateDisplay();

}
23 changes: 23 additions & 0 deletions pattern/src/com/premaseem/ProxyiPhone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.premaseem;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
*/
public class ProxyiPhone implements IPhone{
@Override
public void getColor () {
System.out.println(this.getClass().getSimpleName() +" Colors: Gold, Rose Gold, Carbon Black");
}

@Override
public void getDimension () {
System.out.println(this.getClass().getSimpleName() +" Dimension: Normal and Plus");
}

@Override
public void operateDisplay () {
System.out.println(this.getClass().getSimpleName() +" Sorry, This is proxy object, display will work only in Real object");
}
}
23 changes: 23 additions & 0 deletions pattern/src/com/premaseem/RealiPhone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.premaseem;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
*/
public class RealiPhone implements IPhone{
@Override
public void getColor () {
System.out.println(this.getClass().getSimpleName() +" Colors: Gold, Rose Gold, Carbon Black");
}

@Override
public void getDimension () {
System.out.println(this.getClass().getSimpleName() + " Dimension: Normal and Plus");
}

@Override
public void operateDisplay () {
System.out.println(this.getClass().getSimpleName() +" Multi color display working in real Phone object :-) ");
}
}
13 changes: 0 additions & 13 deletions patternBonus/src/com/premaseem/Client.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package me.premaseem.proxy.protectiveProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Scanner;

public class ClientForProjectiveProxy {

public static void main(String[] args) {

System.out.println("Welcome to Role based access system using protective proxy design pattern ");

Employee employeeBean = new Employee();
employeeBean.setName("premaseem");
employeeBean.setRating(10);
employeeBean.setSalary(1000);

EmployeeInterface employeeProxy;
Scanner scan = new Scanner(System.in);
int repeatRunFlag = 1;

System.out.println("What is your role ? ");
System.out.println("press 1 for Manger");
System.out.println("press 2 for Employee");
int functionalRole = scan.nextInt();

employeeProxy = getRoleBasedAccessEmployeeProxy(employeeBean, functionalRole);

while (repeatRunFlag == 1) {
System.out.println("What do you want to retrieve from Employee record ");
System.out.println(" Press 1 for get Name");
System.out.println(" Press 2 for set Salary ");
System.out.println(" Press 3 for get Salary ");
System.out.println(" Press 4 for set Rating ");
System.out.println(" Press 5 for get Rating ");

int type = scan.nextInt();
try {
switch (type) {
case 1:
System.out.println(employeeProxy.getName());
break;
case 2:
employeeProxy.setSalary(1000);
break;
case 3:
System.out.println(employeeProxy.getSalary());
break;
case 4:
employeeProxy.setRating(10);
break;
case 5:
System.out.println(employeeProxy.getRating());

}
} catch (Exception e1) {
System.out.println("################ Access is not valid ###############");
}
System.out.println("=============================");

System.out.println("Press 1 to continue and 0 for EXIT .... ");
try {
repeatRunFlag = scan.nextInt();
} catch (Exception e) {
repeatRunFlag = 0;
}

}

System.out.println("\n $$$$$$$$$$$$$$$$$$$$ Thanks by Prem Aseem $$$$$$$$$$$$$$$$$$$$$$ \n ");

}

private static EmployeeInterface getRoleBasedAccessEmployeeProxy(Employee employeeBean, int functionalRole) {
InvocationHandler handler = null;
if (functionalRole == 1) {
handler= new ManagerInvocationHandler(employeeBean);
} else {
handler = new EmployeeInvocationHandler(employeeBean);
}
return (EmployeeInterface) Proxy.newProxyInstance(employeeBean.getClass().getClassLoader(), employeeBean.getClass().getInterfaces(),
handler);
}
}
29 changes: 29 additions & 0 deletions patternBonus/src/me/premaseem/proxy/protectiveProxy/Employee.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package me.premaseem.proxy.protectiveProxy;

public class Employee implements EmployeeInterface {

private String name;
private int rating;
private int salary;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package me.premaseem.proxy.protectiveProxy;

public interface EmployeeInterface {


String getName ();
void setName (String name);
int getRating () ;
void setRating (int rating);
int getSalary ();
void setSalary (int salary);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.premaseem.proxy.protectiveProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class EmployeeInvocationHandler implements InvocationHandler {

private EmployeeInterface emp;

public EmployeeInvocationHandler(EmployeeInterface emp){
this.emp = emp;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().contains("setSalary")){
throw new IllegalAccessException();
}
if(method.getName().startsWith("get")){
return method.invoke(emp, args);
}
return null;
}
}


class ManagerInvocationHandler implements InvocationHandler {

private EmployeeInterface emp;

public ManagerInvocationHandler(EmployeeInterface emp){
this.emp = emp;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().contains("Salary")){
throw new IllegalAccessException();
}
if(method.getName().startsWith("get")){
return method.invoke(emp, args);
}
if(method.getName().startsWith("set")){
return method.invoke(emp, args);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Download the working example demo code in java from my GIT repository -https://github.com/premaseem/designPatterns/tree/4bb9beca7bab5b5e71d02b76e4f1ad48fce4aca6/ZipDownloadableProjects
Code example Description :
Doctors are busy and uses proxies / surrogates or say assistant doctors, unless they are not needed. For initial investigation senior doctor or surgeon is not required, hence they make you to interact with their proxy/assistant doctor. However, for operation or consulting they take the charge (replaces the proxy).



Proxy means ‘in place of’. In attendance roll call, we give proxy for our friends in college right? ‘Representing’ or ‘in place of’ or ‘on behalf of’ are literal meanings of proxy and that directly explains proxy design pattern. It is one of the simplest and straight forward design pattern.

Intent :
Provide a surrogate or placeholder for another object to control access to it.
Use an extra level of indirection to support distributed, controlled, or intelligent access.
Add a wrapper and delegation to protect the real component from undue complexity.

Problem :
You need to support resource-hungry objects, and you do not want to instantiate such objects unless and until they are actually requested by the client.

Possible Usage Scenarios :
Remote Proxy – Represents an object locally which belongs to a different address space. Think of an ATM implementation, it will hold proxy objects for bank information that exists in the remote server. RMI is an example of proxy implmenetation for this type in java.
Virtual Proxy – In place of a complex or heavy object use a skeleton representation. When an underlying image is huge in size, just represent it using a virtual proxy object and on demand load the real object. You feel that the real object is expensive in terms of instantiation and so without the real need we are not going to use the real object. Until the need arises we will use the virtual proxy.
Protection Proxy – Are you working on a MNC? If so, you might be well aware of the proxy server that provides you internet. Saying more than provides, the right word is censores internet. The management feels its better to censor some content and provide only work related web pages. Proxy server does that job. This is a type of proxy design pattern.
Smart Reference – Just we keep a link/reference to the real object a kind of pointer.

Structure

By defining a Subject interface, the presence of the Proxy object standing in place of the RealSubject is transparent to the client.
img

Discussion :
Design a surrogate, or proxy, object that: instantiates the real object the first time the client makes a request of the proxy, remembers the identity of this real object, and forwards the instigating request to this real object. Then all subsequent requests are simply forwarded directly to the encapsulated real object.

There are four common situations in which the Proxy pattern is applicable.
A virtual proxy is a placeholder for "expensive to create" objects. The real object is only created when a client first requests/accesses the object.
A remote proxy provides a local representative for an object that resides in a different address space. This is what the "stub" code in RPC and CORBA provides.
A protective proxy controls access to a sensitive master object. The "surrogate" object checks that the caller has the access permissions required prior to forwarding the request.
A smart proxy interposes additional actions when an object is accessed. Typical uses include:



Important Points:
A proxy may hide information about the real object to the client.
A proxy may perform optimization like on demand loading.
A proxy may do additional house-keeping job like audit tasks.
Proxy design pattern is also known as surrogate design pattern.

Check list :
Identify the leverage or "aspect" that is best implemented as a wrapper or surrogate.
Define an interface that will make the proxy and the original component interchangeable.
Consider defining a Factory that can encapsulate the decision of whether a proxy or original object is desirable.
The wrapper class holds a pointer to the real class and implements the interface.
The pointer may be initialized at construction, or on first use.
Each wrapper method contributes its leverage, and delegates to the wrappee object.

Rules of thumb :
Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests.
Loading