Reading Time: 2 minutesProxy Design Pattern in Python
Proxy Design Pattern in Python
Design Patterns Home
What is it?
The Proxy Design Pattern is adopted when you need to postpone the instantiation of a resource-intensive object. A resource-intensive object is an object which requires significant amount of system resources, and hence is expensive to create such as a large file on disk, a network connection etc. The Proxy acts as a placeholder for the actual object. The latter is created by the Proxy only when it is absolutely necessary to create it, or when certain preconditions are met before methods of the real object are invoked. In our example, the resource-intensive object is the Car object, and we will allow the user to drive it only if he is of age.
For the client, accessing the Proxy is similar to accessing the actual object because both have similar methods. The client interacts with the Proxy object most of the time until the object creation becomes mandatory.
The Proxy can also be used to add extra functionality (such as Caching operations) to the actual object. In this way, it is related to the Decorator Pattern.
It is classified under Structural Design Patterns as it offers an industry-wide popular way to organize class hierarchy.
Why the need for it: Problem Statement
The problem that the Proxy Pattern is trying to solve is to postpone the creation of a resource-intensive object unless its creation is necessary or certain preconditions are met.
Terminology
- Proxy: The Proxy is a placeholder class, which creates the resource-intensive object only if it is necessary. The Proxy has similar methods as those of the resource-intensive object. These methods invoke corresponding methods of the resource-intensive object only if it certain conditions are met. This leads to instantiation of the actual object AND calls to its methods, only when they are required, to prevent unnecessary overhead.
Pseudo Code
Consider the following situation: We create an instance of the class Car only when the driver is of permissible age. Our Proxy is in this case is another class CarProxy, who is checking to see if the age of the driver is 18 or above. If yes, then the car is created and the driver is allowed to drive it. If not, the car is not created and consequently driver cannot drive it.
if ageOfDriver > = 18 : |
create instance of Car object & assign to local variable |
call driveCar() of the Car object |
print 'Driver is underage. Can' t drive the car.' |
create an instance of the proxy |
call the driveCar() of the proxy; driver shouldn't be allowed since default age is 15 in the proxy class |
call the driveCar() of the proxy, which instantiates the car object and calls its driveCar() |
How to implement it
print ( "Proxy in action. Checking to see if the driver is of age or underage..." ) |
if self .ageOfDriver > = 18 : |
print ( "Driver is underage. Can't drive the car." ) |
carProxy.ageOfDriver = 21 |
Walkthrough of implementation
- First, we create an object of the Proxy (CarProxy) i.e. carProxy. This carProxy has two attributes, ageOfDriver set to 15 & an empty car variable.
- Then, we call its driveCar() method just like we would have if we had created a Car object.
- The driveCar() of the Proxy checks if ageOfDriver is greater than or equal to 18. It isn't, so it prints a message saying that driver is underage.
- Then, we modify the ageOfDriver attribute of the Proxy object, setting it to 21.
- We call the driveCar() of the Proxy again, and this time, it detects that driver is of age. So, it instantiates a Car object and calls its driveCar() method.
Related to: Adapter & Decorator
See also: