Open In App
Related Articles

Proxy Design Pattern for Object Communication in Python

Like Article
Save Article
Report issue

Memory and time are the two main challenges while working with large objects. So, it is important to reuse these objects to generate new references rather than creating them on every new request. And most importantly, memory must be released after all sections of code have completed working on it.

A proxy design pattern is the best possible way to achieve the initialization of large objects. It separates the client code from the object by creating a surrogate proxy object that behaves like a real object. Here, the client code interacts with the proxy class – it has a real-object instance. Apart from object initialization, it also provides the best possible solutions for logging, network connections, access to shared objects, reference counting, and more.

Some advantages of using a proxy design pattern are:

  1. It ensures distributed, controlled, or intelligent access by using an extra level of indirection
  2. It protects the real object from unnecessary complexity by adding a wrapper.
  3. Avoids inapt object instantiation and can optimize the performance of an application

However, sometimes, the proxy pattern increases the response time from the object – when the object is requested for the first time, it will take more time for object initialization.


Let’s implement a Python code to instantiate a large object, which holds 10 million digits – RealClass. Since it holds a large object, it is better to interact with the object using a proxy  – ProxyClass  – rather than initiating direct communication.

Proxy Design Pattern

First and foremost, let’s create an abstract class  – AbstractClass  – that provides an interface for RealClass and ProxyClass. The abstract class has a method called sort_digits, and the real class inherits from the abstract class. The proxy class uses the instance of RealClass and facilitates client communication.


import abc
import random
class AbstractClass(metaclass=abc.ABCMeta):
    """ interface for real and proxy object """
    def sort_digits(self, reverse=False):
class RealClass(AbstractClass):
    """ RealClass that holds a larger object """
    def __init__(self):
        self.digits = []
        for i in range(1000000):
    def sort_digits(self, reverse=False):
        if reverse:
class ProxyClass(AbstractClass):
    """ A proxy class that has the same interface as RealClass. """
    ref_count = 0
    def __init__(self):
        """ Creates an object if it doesn't exist and caches it otherwise """
        if not getattr(self.__class__, 'cached_object', None):
            self.__class__.cached_object = RealClass()
            print('New object generated')
            print('Using cached object')
        self.__class__.ref_count += 1
        print('Reference Count:', self.__class__.ref_count)
    def sort_digits(self, reverse=False):
        print('Sort method')
        # invokes the sort_digits method of real class
    def __del__(self):
        """ Delete the object when the number of reference is 0 """
        self.__class__.ref_count -= 1
        if self.__class__.ref_count == 0:
            print('Deleting cached object')
            del self.__class__.cached_object
        print('Reference Count:', self.__class__.ref_count)
if __name__ == '__main__':
    proxA = ProxyClass()
    proxB = ProxyClass()
    proxC = ProxyClass()
    print('Deleting proxA')
    del proxA
    print('Deleting proxB')
    del proxB
    print('Deleting proxC')
    del proxC



New object generated Reference Count: 1 Using cached object Reference Count: 2 Using cached object Reference Count: 3 Sort method dict_items([(‘reverse’, True), (‘self’, <__main__.ProxyClass object at 0x7ff50f73e0b8>)]) Deleting proxA Reference Count: 2 Deleting proxB Reference Count: 1 Deleting proxC Deleting cached object Reference Count: 0

Let’s look into the ProxyClass design. It creates an instance of the RealClass if it’s not been created before. If the object already exists, the proxy class increments the reference count and returns a new link to the real class. And the sort method in the proxy class calls the sort method of the real class, using the cached reference. In the end, the destructor method decreases the reference count on every call, and when there are no references left, it deletes the object.  

Proxy design pattern optimizes the performance of an application by caching the frequently used objects and also improves the security of an application by checking the access rights. Apart from these, it facilitates remote system interactions.

Last Updated : 25 Oct, 2020
Like Article
Save Article
Share your thoughts in the comments
Similar Reads