You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
3.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

'''
访问者模式Visitor Pattern
表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式Visitor Pattern可以用于将操作逻辑从对象结构中分离出来。假设我们有一个书城系统其中包含不同类型的书籍如小说、教材等我们想要对不同类型的书籍执行不同的操作如打印价格、增加库存等。访问者模式允许我们定义一个新的操作而无需改变书籍的类结构。
'''
# 书籍类作为元素Element角色
class Book:
def __init__(self, title, price, category):
self.title = title
self.price = price
self.category = category
def accept(self, visitor):
visitor.visit(self)
# 小说类,继承自书籍类
class NovelBook(Book):
def __init__(self, title, price):
super().__init__(title, price, "Novel")
# 教材类,继承自书籍类
class Textbook(Book):
def __init__(self, title, price):
super().__init__(title, price, "Textbook")
# 访问者接口
class IVisitor:
def visit(self, book):
pass
# 具体的访问者类,实现访问者接口
class PricePrinter(IVisitor):
def visit(self, book):
print(f"Price of '{book.title}': ${book.price}")
class StockAdder(IVisitor):
def __init__(self, additional_stock):
self.additional_stock = additional_stock
def visit(self, book):
# 假设这里有一个增加库存的方法,实际上应该通过数据库或其他方式更新
print(f"Adding {self.additional_stock} copies of '{book.title}' to stock")
# 客户端代码
if __name__ == "__main__":
# 创建书籍对象
novel = NovelBook("The Great Gatsby", 19.99)
textbook = Textbook("Introduction to Algorithms", 49.99)
# 创建访问者对象
price_printer = PricePrinter()
stock_adder = StockAdder(5)
# 书籍接受访问者
novel.accept(price_printer)
textbook.accept(price_printer)
# 增加库存操作
novel.accept(stock_adder)
textbook.accept(stock_adder)
'''
在这个示例中Book 类是元素角色,它包含一个 accept 方法该方法接受一个访问者对象。NovelBook 和 Textbook 是具体元素,它们继承自 Book 类。IVisitor 是访问者接口,声明了一个 visit 方法。PricePrinter 和 StockAdder 是实现了 IVisitor 接口的具体访问者类,它们分别用于打印书籍价格和增加书籍库存。
客户端代码创建了书籍对象和访问者对象,并通过调用书籍的 accept 方法来接受访问者的访问。这样,访问者就可以对书籍执行相应的操作。
需要注意的是,访问者模式的一个主要缺点是增加新的操作意味着增加新的访问者类,这可能会导致类的数量增加。此外,如果需要在访问者中访问对象结构的复杂关系,代码可能会变得难以理解和维护。因此,在使用访问者模式时需要权衡其优缺点。
'''