Category Archives: General

Proxy Pattern

In proxy pattern, a class represents functionality of another class. This type of design pattern comes under structural pattern.

In proxy pattern, we create object having original object to interface its functionality to outer world.

import abc
class Greeter(abc.ABC):
@abc.abstractmethod
def greet(self):
pass

class RealGreeter(Greeter):
def __init__(self, name):
self.name = name
def greet(self):
return str("Hello " + self.name)

class GreaterProxy(Greeter):
greeter = None
def greet(cls, name):
# Check if the user is authorized before calling real greater
# Check real greater is available ( resources )

if cls.greeter == None:
cls.greeter = RealGreeter(name)
else:
cls.greeter.name = name
return cls.greeter.greet()

proxy = GreaterProxy()
print(proxy.greet("Chang"))

Flyweight Pattern

"""
The flyweight software design pattern refers to an object that minimizes memory usage by sharing some of its data with other similar objects.
Flyweight is a structural design pattern that lets you fit more objects into the available amount of RAM by sharing common parts of state between multiple objects instead of keeping all of the data in each object.

Save Object in hashMap and used it again and again
"""
import abc
class Shape(abc.ABC):
@abc.abstractmethod
def draw(self):
pass

class Triangle(Shape):
def draw(self):
print("Triangle")

class Circle(Shape):
def __init__(self, color):
self.color = color
def setX(self, x):
self.x = x
def setY(self, y):
self.y = y
def setRadius(self, r):
self.radius = r
def draw(self):
print(f"Circle color {self.color} {self.x}:{self.y}")

class ShapeFactory:
def __init__(self):
self.circleMap = dict()
def getCircle(self, color):
if color not in self.circleMap:
self.circleMap[color] = Circle(color)
print("Creating circle of color : " + color)
return self.circleMap[color]

import random
def main():
colors = ["Red", "Green", "Blue", "White", "Black"]
circleFactory = ShapeFactory()
for i in range(50):
circle = circleFactory.getCircle(random.choice(colors))
circle.setX(random.randrange(0, 100))
circle.setY(random.randrange(0, 100))
circle.setRadius(random.randrange(0, 1000))
circle.draw()

if __name__ == "__main__":
main()
class Grade(object):
_instances = {}
def __new__(cls, percent):
percent = max(50, min(99, percent))
letter = 'FDCBA'[(percent - 50) // 10]
self = cls._instances.get(letter)
if self is None:
self = cls._instances[letter] = object.__new__(Grade)
self.letter = letter
return self

def __repr__(self):
return 'Grade {!r}'.format(self.letter)

def grademain():
print(len(Grade._instances))
for _ in range(100):
Grade(random.randint(0, 100))
print(len(Grade._instances)) # number of instances
for instance in Grade._instances.values():
print(instance)

grademain()

Visitor Pattern

When you have File class with all print(), email() with inherited classes to WordFile, PictireFile, PreadSheet, …. Your new requirement are adding compress method on each classes. This is simple hierarchy structure. To add compress function you need to visit every class inherited from File. For visitor class you can create CompressVisitor class with visiteWord, visitPictire, visitSpeadSheet.

As per the pattern, element object has the visitor object so that visitor object handles the operation on the element object.

import abc
class File(abc.ABC):
def __init__(self, txt):
self.txt = txt
@abc.abstractmethod
def visit(self):
pass
class WordFile(File):
def __init__(self, txt):
super().__init__(txt)
def visit(self, fileVisitor):
fileVisitor.visitWord(self)
def __str__(self):
return self.txt

class PictureFile(File):
def __init__(self, txt):
super().__init__(txt)
def visit(self, fileVisitor):
fileVisitor.visitPicture(self)
def __str__(self):
return self.txt

class FileVisitor(abc.ABC):
@abc.abstractmethod
def visitWord(self):
pass
@abc.abstractmethod
def visitPicture(self):
pass

class PrintVisitor(FileVisitor):
def visitWord(self, wordFile):
print("Print Visitor ", wordFile)

def visitPicture(self, pictureFile):
print("Print Visitor ", pictureFile)

class EmailVisitor(FileVisitor):
def visitWord(self, wordFile):
print("Email Visitor ", wordFile)

def visitPicture(self, pictureFile):
print("Email Visitor ", pictureFile)

class CompressVisitor(FileVisitor):
def visitWord(self, wordFile):
print("Compress Visitor ", wordFile)

def visitPicture(self, pictureFile):
print("Compress Visitor ", pictureFile)

l = list()
l.append(WordFile("wordFile"))
l.append(PictureFile("pictireFile"))

printv = PrintVisitor()
for f in l:
f.visit(printv)

compressv = CompressVisitor()
for f in l:
f.visit(compressv)

emailv = EmailVisitor()
for f in l:
f.visit(emailv)
import abc
class Animal(abc.ABC):
@abc.abstractmethod
def visit(self, obj):
pass

class Dog(Animal):
def __init__(self, name):
self.name = name
def visit(self, visitor):
visitor.visit(self)
class Cat(Animal):
def __init__(self, name):
self.name = name
def visit(self, visitor):
visitor.visit(self)
class Horse(Animal):
def __init__(self, name):
self.name = name
def visit(self, visitor):
visitor.visit(self)
class Cow(Animal):
def __init__(self, name):
self.name = name
def visit(self, visitor):
visitor.visit(self)
class Visitor:
def visit(self, obj):
if isinstance(obj, Dog):
print(f"Take a walk for 30 min with {obj.name}")
elif isinstance(obj, Cat):
print(f"Let {obj.name} alone")
elif isinstance(obj, Horse):
print(f"Ride {obj.name} for horse riding")
elif isinstance(obj, Cow):
print(f"Extract milk for {obj.name}")

farm = [Dog("Willie"), Cat("Billie"), Horse("Charle"), Cow("Bullie"), Dog("Zollie")]
visitor = Visitor()
for anmimal in farm:
anmimal.visit(visitor)