Visitor design pattern allows the addition of completely different functionalities to an existing class without much alteration in the original class.
Let me explain it with an example.
Suppose there are two items a shop sells - Book and Medicine
Now say, normally these two Item classes would look like two - what we call in Java as POJO classes where the most important attribute will be the price.
So far so good.
Now suppose the government is running
- one literacy mission
and
- one Health mission
Under these missions, few books are given huge discounts, and few medicines are sold at discounted prices.
Without the Visitor pattern, the algorithm of the discounts would have been put inside the POJO classes which might create maintenance problems in the future when the algorithm for discount changes.
With the visitor pattern, we encapsulate all these discount algorithms inside a special method called visit which comes from a Visitor interface.
So if it is a LiteracyMissionVisitor, the special algorithm offers a discount on special books whereas if it is a HealthMissionVisitor, the discount goes to specific medicines – all we have to do is to call accept on these special Book and Medicine objects passing the proper Visitor object,
That's it...
The UML class diagram looks as follows:
And here goes the source code of this Visitor Pattern
from abc import ABC, abstractmethod
class Visitor(ABC):
@abstractmethod
def visit(self, book):
pass
@abstractmethod
def visit(self, medicine):
pass
class Visitable(ABC):
@abstractmethod
def accept(self, visitor):
pass
class Book(Visitable):
def __init__(self, price):
self.price = price
def accept(self, visitor):
return visitor.visit(self)
def getPrice(self):
return self.price
class Medicine(Visitable):
def __init__(self, price):
self.price = price
def accept(self, visitor):
return visitor.visit(self)
def getPrice(self):
return self.price
class LiteracyMissionVisitor(Visitor):
def __init__(self, percentagediscountOnBook):
self.discount = percentagediscountOnBook
def visit(self, book):
book.price = book.price - (book.price * self.discount)/100
return book.price
class HealthMissionVisitor(Visitor):
def __init__(self, percentagediscountOnMedicine):
self.discount = percentagediscountOnMedicine
def visit(self, medicine):
medicine.price = medicine.price - (medicine.price * self.discount)/100
return medicine.price
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
literacyMissionVisitor = LiteracyMissionVisitor(50)
chandaMama = Book(100)
print("Original price of the book is ", chandaMama.getPrice())
print("Due to literacy mission, there is huge discount on the book.
After discount, the price is ", chandaMama.accept(literacyMissionVisitor))
healthDriveVisitor = HealthMissionVisitor(70)
vitaminDCapsule = Medicine(200)
print("Original price of the medinine is ", vitaminDCapsule.getPrice())
print("Due to health mission the reduced price of the
medicine is ", vitaminDCapsule.accept(healthDriveVisitor))
If we run this program, the output will be as follows:
Original price of the book is 100
Due to literacy mission, there is huge discount on the book. After discount, the price is 50.0
Original price of the medinine is 200
Due to health mission the reduced price of the medicine is 60.0
No comments:
Post a Comment