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

9 months ago
'''
访问者模式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 方法来接受访问者的访问这样访问者就可以对书籍执行相应的操作
需要注意的是访问者模式的一个主要缺点是增加新的操作意味着增加新的访问者类这可能会导致类的数量增加此外如果需要在访问者中访问对象结构的复杂关系代码可能会变得难以理解和维护因此在使用访问者模式时需要权衡其优缺点
'''