访问者模式的核心是将数据结构与数据操作分离,允许你在不修改原有数据结构(珠宝类)的前提下,为其增加新的操作(比如估值、鉴定、清洁)。下面我会用珠宝(钻石、黄金、翡翠)作为核心数据结构,用不同的访问者(估值师、鉴定师、清洁师)作为操作,完整实现并解释这个模式。
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:40
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : Jewelry.py
from abc import ABC, abstractmethod
# ====================== 1. 定义元素(珠宝)接口 ======================
class Jewelry(ABC):
"""
珠宝抽象类(元素接口),定义接受访问者的方法
"""
@abstractmethod
def accept(self, visitor):
"""
接受访问者访问的核心方法
:param visitor:
:return:
"""
pass
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:41
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : Diamond.py
from VisitorPattern.Jewelry import Jewelry
# ====================== 2. 具体元素(各类珠宝) ======================
class Diamond(Jewelry):
"""
钻石(具体元素)
"""
def __init__(self, carat: float, clarity: str):
"""
:param carat:
:param clarity:
"""
self.carat = carat # 克拉
self.clarity = clarity # 净度(VS1、VVS1等)
def accept(self, visitor):
"""
调用访问者的「访问钻石」方法,并传入自身
:param visitor:
:return:
"""
visitor.visit_diamond(self)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:42
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : Gold.py
from VisitorPattern.Jewelry import Jewelry
# ====================== 2. 具体元素(各类珠宝) ======================
class Gold(Jewelry):
"""
黄金(具体元素)
"""
def __init__(self, weight: float, purity: float):
"""
:param weight:
:param purity:
"""
self.weight = weight # 克重
self.purity = purity # 纯度(如999、9999)
def accept(self, visitor):
"""
:param visitor:
:return:
"""
visitor.visit_gold(self)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:43
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : Jade.py
from VisitorPattern.Jewelry import Jewelry
# ====================== 2. 具体元素(各类珠宝) ======================
class Jade(Jewelry):
"""
翡翠(具体元素)
"""
def __init__(self, grade: str, size: float):
"""
:param grade:
:param size:
"""
self.grade = grade # 品级(A、B、C)
self.size = size # 尺寸(cm³)
def accept(self, visitor):
"""
:param visitor:
:return:
"""
visitor.visit_jade(self)
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:45
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryVisitor.py
from VisitorPattern.Gold import Gold
from VisitorPattern.Jade import Jade
from VisitorPattern.Diamond import Diamond
from abc import ABC, abstractmethod
# ====================== 3. 定义访问者接口 ======================
class JewelryVisitor(ABC):
"""
珠宝访问者抽象接口,定义对所有珠宝的访问方法
"""
@abstractmethod
def visit_diamond(self, diamond: Diamond):
"""
:param diamond:
:return:
"""
pass
@abstractmethod
def visit_gold(self, gold: Gold):
"""
:param gold:
:return:
"""
pass
@abstractmethod
def visit_jade(self, jade: Jade):
"""
:param jade:
:return:
"""
pass
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:48
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : ValuationVisitor.py
from VisitorPattern.Gold import Gold
from VisitorPattern.Jade import Jade
from VisitorPattern.Diamond import Diamond
from VisitorPattern.JewelryVisitor import JewelryVisitor
# ====================== 4. 具体访问者(不同操作) ======================
class ValuationVisitor(JewelryVisitor):
"""
估值访问者:为不同珠宝计算价值
"""
def __init__(self):
"""
"""
self.total_value = 0 # 总估值
def visit_diamond(self, diamond: Diamond):
"""
钻石估值:克拉 * 净度系数(VVS1=10000, VS1=8000)
:param diamond:
:return:
"""
clarity_coeff = 10000 if diamond.clarity == "VVS1" else 8000
value = diamond.carat * clarity_coeff
self.total_value += value
print(f"钻石({diamond.carat}克拉,{diamond.clarity})估值:{value} 元")
def visit_gold(self, gold: Gold):
"""
黄金估值:克重 * 纯度系数 * 基础金价(假设基础金价400元/克)
:param gold:
:return:
"""
purity_coeff = gold.purity / 999 # 999纯金系数为1
value = gold.weight * purity_coeff * 400
self.total_value += value
print(f"黄金({gold.weight}克,{gold.purity}纯)估值:{value:.2f} 元")
def visit_jade(self, jade: Jade):
"""
翡翠估值:尺寸 * 品级系数(A=5000, B=1000, C=100)
:param jade:
:return:
"""
grade_coeff = {"A": 5000, "B": 1000, "C": 100}[jade.grade]
value = jade.size * grade_coeff
self.total_value += value
print(f"翡翠({jade.size}cm³,{jade.grade}级)估值:{value} 元")
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:50
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : AppraisalVisitor.py
from VisitorPattern.Gold import Gold
from VisitorPattern.Jade import Jade
from VisitorPattern.Diamond import Diamond
from VisitorPattern.JewelryVisitor import JewelryVisitor
# ====================== 4. 具体访问者(不同操作) ======================
class AppraisalVisitor(JewelryVisitor):
"""
鉴定访问者:鉴定珠宝真伪/品质
"""
def visit_diamond(self, diamond: Diamond):
"""
:param diamond:
:return:
"""
result = "真品" if diamond.clarity in ["VVS1", "VS1"] else "仿品"
print(f"钻石鉴定结果:{result}(净度{diamond.clarity})")
def visit_gold(self, gold: Gold):
"""
:param gold:
:return:
"""
result = "足金" if gold.purity >= 999 else "非足金"
print(f"黄金鉴定结果:{result}(纯度{gold.purity})")
def visit_jade(self, jade: Jade):
"""
:param jade:
:return:
"""
result = "天然翡翠" if jade.grade == "A" else "处理翡翠"
print(f"翡翠鉴定结果:{result}(品级{jade.grade})")
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:51
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : CleaningVisitor.py
from VisitorPattern.Gold import Gold
from VisitorPattern.Jade import Jade
from VisitorPattern.Diamond import Diamond
from VisitorPattern.JewelryVisitor import JewelryVisitor
# ====================== 4. 具体访问者(不同操作) ======================
class CleaningVisitor(JewelryVisitor):
"""
清洁访问者:根据珠宝类型执行不同清洁方式
"""
def visit_diamond(self, diamond: Diamond):
"""
:param diamond:
:return:
"""
print(f"钻石清洁:使用超声波清洗(适配{diamond.clarity}净度)")
def visit_gold(self, gold: Gold):
"""
:param gold:
:return:
"""
print(f"黄金清洁:使用高温蒸汽清洗(适配{gold.purity}纯度)")
def visit_jade(self, jade: Jade):
"""
:param jade:
:return:
"""
print(f"翡翠清洁:使用软布擦拭(适配{jade.grade}品级)")
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:53
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : JewelryCollection.py
from VisitorPattern.Jewelry import Jewelry
from VisitorPattern.JewelryVisitor import JewelryVisitor
# ====================== 5. 对象结构(珠宝集合) ======================
class JewelryCollection(object):
"""
珠宝集合:管理所有珠宝,提供遍历访问的方法
"""
def __init__(self):
"""
"""
self.jewelry_items = []
def add_jewelry(self, jewelry: Jewelry):
"""
:param jewelry:
:return:
"""
self.jewelry_items.append(jewelry)
def accept(self, visitor: JewelryVisitor):
"""
遍历所有珠宝,让访问者访问每一个
:param visitor:
:return:
"""
for item in self.jewelry_items:
item.accept(visitor)
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:访问者模式(Visitor Pattern)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/2/23 17:55
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : VisitorBll.py
from VisitorPattern.Gold import Gold
from VisitorPattern.Jade import Jade
from VisitorPattern.Diamond import Diamond
from VisitorPattern.CleaningVisitor import CleaningVisitor
from VisitorPattern.ValuationVisitor import ValuationVisitor
from VisitorPattern.AppraisalVisitor import AppraisalVisitor
from VisitorPattern.JewelryCollection import JewelryCollection
class VisitorBll(object):
"""
示例
"""
def demo(self):
"""
:return:
"""
# 1. 创建珠宝集合并添加珠宝
collection = JewelryCollection()
collection.add_jewelry(Diamond(1.2, "VVS1")) # 1.2克拉VVS1钻石
collection.add_jewelry(Gold(20.5, 999)) # 20.5克999纯金
collection.add_jewelry(Jade("A", 5.0)) # 5cm³A级翡翠
print("=" * 50 + "\n1. 珠宝估值")
valuer = ValuationVisitor()
collection.accept(valuer)
print(f"所有珠宝总估值:{valuer.total_value:.2f} 元")
print("=" * 50 + "\n2. 珠宝鉴定")
appraiser = AppraisalVisitor()
collection.accept(appraiser)
print("=" * 50 + "\n3. 珠宝清洁")
cleaner = CleaningVisitor()
collection.accept(cleaner)
调用:
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2023.1 python 3.11
# OS : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j
# Datetime : 2026/2/18 20:58
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : main.py
# explain : 学习
from bll.MementoBll import MementoBll
from bll.CommandBll import CommandBll
from bll.StateBll import StateBll
from bll.TemplateMethodBll import TemplateMethodBll
from bll.VisitorBll import VisitorBll
if __name__ == '__main__':
#实现备忘录模式(Memento Pattern)
#mementobll= MementoBll()
#mementobll.demo()
#命令模式(Command Pattern)
#commandBll= CommandBll()
#commandBll.demo()
# 状态模式 State Pattern
#stateBll =StateBll()
#stateBll.demo()
# 模板方法模式 Template Method Pattern
#templateMethodBll= TemplateMethodBll()
#templateMethodBll.demo()
# 访问者模式(Visitor Pattern)
visitor = VisitorBll()
visitor.demo()
print('hi,welcome geovindu.')
输出:
