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)

Leave a Reply