Python Design Patterns — Proxy Pattern — Controlling object access

Introduction

Proxy pattern can be used in following scenarios -

  • When complex system is built, it would be helpful to provide proxy interface for client’s benefit.
  • When you need more security before reaching to real objects
  • When you need multiple server’s access through one server with security
  • To avoid loading heavy memory real objects until they needed to be loaded.

Let’s understand proxy pattern using example of Personal Assistant and CEO

class CEO(object):
def __init__(self):
self.is_available = True
def occupied(self):
self.is_available = False
print("CEO is busy in meeting")
def available(self):
self.is_available = True
print("CEO is available for meeting")
@propery
def status(self):
return self.is_available
class PersonalAssistant(object):
def talk(self):
self.ceo = CEO()
if self.ceo.status:
self.actor.occupied()
else:
self.actor.available()
if __name__ == '__main__':
pa = PersonalAssistant()
pa.talk()
class RealImages(object):
def get_image(self, id):
print("Here is your image - Image 1")
class Proxy(object)
def __init__(self):
self.real_images = RealImages()
self.images = []
def get_image(self, id):
if id in self.images:
print("Here is your cached image")
else:
self.real_images.get_image(id)
  • Surrogate class to real objects.
  • Provides layer for supporting distribution or real objects
  • Delegate and protect real objects.
  1. Virtual proxy
  2. Remote proxy abc.pdf
  3. Protective proxy
  4. Smart proxy

Virtual Proxy

Remote Proxy

Protective proxy

Smart Proxy

Now let’s look at the real life example -

import abcclass AbstractCmd(metaclass=abc.ABCMeta):    @abc.abstractmethod
def execute(self, command):
pass
class RealCmd(AbstractCmd): def execute(self, command):
print(f"{command} command executed.")
class ProxyCmd(AbstractCmd): def __init__(self, user):
self.is_authorized = False
if user == "admin":
self.is_authorized = True
self.executor = RealCmd()
self.restricted_commands = ['rm', 'mv']
def execute(self, command):
if self.is_authorized:
self.executer.execute(command)
else:
if any([command.strip().startswith(cmd)
for cmd in self.restricted_commands]):
raise Exception(f"{command} command is not allowed for non-admin users.")
else:
self.executer.execute(command)
if __name__ == '__main__':
admin_executor = ProxyCmd("Admin")
other_executor = ProxyCmd("Other")
try:
admin_executor.execute("ls -la");
admin_executor.execute("rm -rf /");
other_executor.execute("ls -la");
other_executor.execute("rm -rf");
except Exception as e:
print(e)

Benefits of Proxy pattern

  • It helps to improve performance by caching heavy objects and frequently used objects.
  • It helps to implement authorization to restrict real objects access.
  • It also helps in networking application like monitoring distributed systems.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store