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)

Facade Pattern

Facade pattern hides the complexities of the system and provides an interface to the client using which the client can access the system. This type of design pattern comes under structural pattern as this pattern adds an interface to existing system to hide its complexities.

class Compiler:
def __init__(self, path):
self.path = path
def compile(self):
tokenizer = Tokenizer(self.path).tokenize()
parser = Parser(tokenizer).parse()
builder = IRBuilder(parser).build()
optimizer = Optimizer(builder).optimize()
codegenerator = CodeGenerator(optimizer).generate()
linker = Linker(codegenerator).link()
return linker
class Tokenizer:
def __init__(self, path):
self.path = path
def tokenize(self):
print(f"tokenizing {self.path}")
return self
def __str__(self):
return "Tokenizer"
class Parser:
def __init__(self, tokenizer):
self.tokenizer = tokenizer
def parse(self):
print("parsinging", end=" ")
print(self.tokenizer)
return self
def __str__(self):
return "Parser"
class IRBuilder:
def __init__(self, parser):
self.parser = parser
def build(self):
print("IRbuilding", end=" ")
print(self.parser)
return self
def __str__(self):
return "IRBuilder"
class Optimizer:
def __init__(self, builder):
self.builder = builder
def optimize(self):
print("optimizing", end=" ")
print(self.builder)
return self
def __str__(self):
return "Optimizer"
class CodeGenerator:
def __init__(self, optimizer):
self.optimizer = optimizer
def generate(self):
print("generating code", end=" ")
print(self.optimizer)
return self
def __str__(self):
return "CodeGenerator"
class Linker:
def __init__(self, generator):
self.codegenerator = generator
def link(self):
print("linking",end=" ")
print(self.codegenerator)
return self
def __str__(self):
return "Linker"
compiler = Compiler("sample.py")
compiler.compile()
class Washing:
'''Subsystem # 1'''
def wash(self):
print("Washing...")


class Rinsing:
'''Subsystem # 2'''
def rinse(self):
print("Rinsing...")


class Spinning:
'''Subsystem # 3'''
def spin(self):
print("Spinning...")

class WashingMachine:
'''Facade'''

def __init__(self):
self.washing = Washing()
self.rinsing = Rinsing()
self.spinning = Spinning()

def startWashing(self):
self.washing.wash()
self.rinsing.rinse()
self.spinning.spin()