Reading Time: 1 minutes
Visitor Design Pattern in Python
What is it?
The Visitor Design Pattern is adopted to add new features to an existing class hierarchy dynamically without changing it.
It is classified under Behavioural Design Patterns as it provides a good method to handle communication between objects.
Why the need for it: Problem Statement
The need for the Visitor Design Pattern arises when there is a requirement to add new operations to existing classes dynamically with minimal/no code changes.
Pseudo Code
# The Crops hierarchy cannot be changed to add new functionality dynamically. # Abstract Crop class for Concrete Crop classes: methods defined in this class will be inherited by all Concrete Crop classes. class Crop: def accept(visitor): calls visitor's visit() def sow(visitor): method to be invoked by one of the visitors def irrigate(visitor): method to be invoked by one of the visitors def harvest(visitor): method to be invoked by one of the visitors def __str__(self): returns name of crop class when printed # Concrete Crops: Classes being visited. class Wheat(Crop): pass class Corn(Crop): pass class Tomato(Crop): pass # Abstract Visitor class for Concrete Visitor classes: method defined in this class will be inherited by all Concrete Visitor classes. class Visitor: def __str__(self): returns name of visitor class when printed # Concrete Visitors: Classes visiting Concrete Crop objects. These classes have a visit() method which is called by the accept() method of the Concrete Crop classes. class GardenerOne(Visitor): def visit(crop): calls a method of the crop class, say sow() class GardenerTwo(Visitor): def visit(crop): calls a method of the crop class, say irrigate() class GardenerThree(Visitor): def visit(crop): calls a method of the crop class, say harvest() ### USING THE ABOVE SETUP ### # Create Plants # Create Visitors # Call accept method of plant objects, one by one, passing a visitor as argument
How to implement it
# The Crops hierarchy cannot be changed to add new functionality dynamically. # Abstract Crop class for Concrete Crop classes: methods defined in this class will be inherited by all Concrete Crop classes. class Crop: def accept(self, visitor): visitor.visit(self) def sow(self, visitor): print(self, "Sown by", visitor) def irrigate(self, visitor): print(self, "Irrigated by", visitor) def harvest(self, visitor): print(self, "Harvested by", visitor) def __str__(self): return self.__class__.__name__ # Concrete Crops: Classes being visited. class Wheat(Crop): pass class Corn(Crop): pass class Tomato(Crop): pass # Abstract Visitor class for Concrete Visitor classes: method defined in this class will be inherited by all Concrete Visitor classes. class Visitor: def __str__(self): return self.__class__.__name__ # Concrete Visitors: Classes visiting Concrete Crop objects. These classes have a visit() method which is called by the accept() method of the Concrete Crop classes. class GardenerOne(Visitor): def visit(self, crop): crop.sow(self) class GardenerTwo(Visitor): def visit(self, crop): crop.irrigate(self) class GardenerThree(Visitor): def visit(self, crop): crop.harvest(self) ### USING THE ABOVE SETUP ### # Creating Plants wheatPatch = Wheat() cornPatch = Corn() tomatoPatch = Tomato() # Creating Visitors gardenerOne = GardenerOne() gardenerTwo = GardenerTwo() gardenerThree = GardenerThree() # Visitors visiting Plants wheatPatch.accept(gardenerOne) wheatPatch.accept(gardenerTwo) wheatPatch.accept(gardenerThree) cornPatch.accept(gardenerOne) cornPatch.accept(gardenerTwo) cornPatch.accept(gardenerThree) tomatoPatch.accept(gardenerOne) tomatoPatch.accept(gardenerTwo) tomatoPatch.accept(gardenerThree) ### OUTPUT ### Wheat Sown by GardenerOne Wheat Irrigated by GardenerTwo Wheat Harvested by GardenerThree Corn Sown by GardenerOne Corn Irrigated by GardenerTwo Corn Harvested by GardenerThree Tomato Sown by GardenerOne Tomato Irrigated by GardenerTwo Tomato Harvested by GardenerThree
- Creational Patterns
- Factory
- Abstract Factory
- Prototype
- Singleton
- Builder
- Architectural Pattern
- Model View Controller (MVC)