Proxy Pattern
- is a type of structural design pattern that provides a surrogate or placeholder for another object to control access to it
Proxy Pattern - Types
- Remote Proxy - local representative of remote object, hides remote calls (RPC/RMI/REST/etc)
- Virtual (Lazy-Load) Proxy - lazy creation of expensive objects (real object is only created when a client first requests/accesses the object)
- Access/Protective Proxy – control access to the sensitive object/subject
- Smart Proxy - reference counting, caching, lazy DB loading
Real-World Example
Wizard Tower Example
Imagine a tower where the local wizards go to study their spells. The ivory tower can only be accessed through a proxy which ensures that only the first three wizards can enter. Here the proxy represents the functionality of the tower and adds access control to it
Code Example
Wizard Tower Example
Take our wizard tower example from above. Firstly we have the
WizardTowerinterface and theIvoryTowerclass.public interface WizardTower { void enter(Wizard wizard); } @Slf4j public class IvoryTower implements WizardTower { public void enter(Wizard wizard) { LOGGER.info("{} enters the tower.", wizard); } }Then a simple Wizard class.
public class Wizard { private final String name; public Wizard(String name) { this.name = name; } @Override public String toString() { return name; } } ```Then we have the <code>WizardTowerProxy</code> to add access control to <code>WizardTower</code>.@Slf4j
public class WizardTowerProxy implements WizardTower {private static final int NUM_WIZARDS_ALLOWED = 3;
private int numWizards;
private final WizardTower tower;
public WizardTowerProxy(WizardTower tower) {
this.tower = tower;
}@Override
public void enter(Wizard wizard) {
if (numWizards < NUM_WIZARDS_ALLOWED) {
tower.enter(wizard);
numWizards++;
} else {
LOGGER.info(”{} is not allowed to enter!”, wizard);
}
}
}And here is the tower entering scenario.var proxy = new WizardTowerProxy(new IvoryTower());
proxy.enter(new Wizard(“Red wizard”));
proxy.enter(new Wizard(“White wizard”));
proxy.enter(new Wizard(“Black wizard”));
proxy.enter(new Wizard(“Green wizard”));
proxy.enter(new Wizard(“Brown wizard”));Program output:Red wizard enters the tower.
White wizard enters the tower.
Black wizard enters the tower.
Green wizard is not allowed to enter!
Brown wizard is not allowed to enter!
Comparisons
Click here to expand...
Link to originalAdapter Pattern vs Proxy Pattern:
- intent: adapter makes an incompatible interface compatible, proxy controls access, add behavior, or delay creation
- who initiates: in adapter, client uses adapter to speak to old legacy code, in proxy client uses proxy as real object
- transparency: in adapter client knows, in proxy client may not know
Link to originalDecorator Pattern vs Proxy Pattern
- Decorator and Proxy have similar structures / same interface as their wrapped types, but different intent
- Proxy creates an instance under the hood, Decorator takes an instance in the constructor
- Differences between Proxy and Decorator Pattern