Proxy¶
Proxy is one of the structural patterns that, in terms of authoring, has a similar structure to Decorator. This pattern adds a layer between the interface and the specific implementation. This layer, depending on the type of proxy we implement, may fulfill a different function.
We can distinguish several types of proxies. Some of them are:
remote
, the purpose of which is to represent an object located in another space (e.g. a remote machine)virtual
, which can be used as a cache for an object referencesecurity
, which adds a layer of security to the object
A proxy
object should implement the same interface as the object it wraps. Very often the end user of an interface does not know that he uses a proxy, which also means that a proxy can hide some implementation details.
The following example shows a simple implementation of the Proxy
pattern of type remote
. The user uses the Image
interface to display images, and the proxy hides their source (disk or Internet), additionally ensuring lazy loading (only when the client wants to display them).
The example consists of the following classes:
Image
- represents the image interface that the client usesRemoteImage
- interface representing remote image - proxy uses it to lazy loadingDiskImage
,InternetImage
- specific implementations of imagesImageProxy
- The 'proxy' used by the client, hides the image source and ensures lazy loading
class Image:
def show(self):
pass
class RemoteImage(Image):
def load_from_source(self):
pass
def is_loaded(self):
pass
class DiskImage(RemoteImage):
def load_from_source(self):
pass
def is_loaded(self):
pass
def show(self):
pass
class InternetImage(RemoteImage):
def load_from_source(self):
pass
def is_loaded(self):
pass
def show(self):
pass
class ImageProxy(Image):
def __init__(self, remote_image):
self._remote_image = remote_image
def show(self):
if not self._remote_image.is_loaded():
self._remote_image.load_from_source()
return self._remote_image.show()
def main():
disk_image_proxy = ImageProxy(DiskImage())
internet_image_proxy = ImageProxy(InternetImage())
# the user only uses the Image interface
disk_image_proxy.show() # the proxy only loads the image when it is needed
# the picture from the Internet is never loaded
if __name__ == '__main__':
main()