自定义访问者模式实现疑问:方法命名与正确性验证
你的访问者模式实现完全合规,且命名方式更优!
Let's tackle your two questions one by one:
1. 新增CalculateExtraCharge方法是否违背访问者模式规范?
完全不违背——反而这种实现更贴合实际业务场景,完美契合访问者模式的核心意图:将多变的操作逻辑从稳定的元素类(这里的CreditCard、Check)中分离出来。
访问者模式的本质是让你可以在不修改元素类的前提下,为元素新增任意多的操作。你的代码里,CalculateFee和CalculateExtraCharge是两个独立的业务操作(计算手续费、计算额外费用),把它们都放到访问者类中实现,刚好利用了访问者模式的优势:
- 元素类(
CreditCard、Check)只需要提供接受访问的入口(GetFee、GetExtraCharge),不需要关心具体计算逻辑; - 后续如果要新增其他操作(比如
CalculateDiscount),只需要在访问者接口和实现类里加对应的重载方法,元素类只需要新增一个GetDiscount方法即可,完全符合开闭原则。
这种“多组访问操作”的实现是访问者模式的常见扩展用法,很多实际项目里都会这么做,避免把所有逻辑塞到单一方法里导致代码臃肿。
2. 是否必须将访问方法命名为visit?
绝对不需要!
GoF(四人帮)的原始设计模式定义里用visit只是一个示例命名,并非强制规范。访问者模式的核心是方法重载实现的双分派机制,而不是方法叫什么名字。
你用CalculateFee、CalculateExtraCharge这种语义化的命名反而更好:
- 代码可读性大幅提升,别人一看就知道这个方法的业务用途;
- 当有多个操作时,不同的方法名能清晰区分逻辑,避免混淆。
额外小建议
如果后续业务还会新增更多支付相关的计算操作,可以继续沿用这个模式:
- 在
IPaymentCalculationsVisitor中新增对应方法(比如decimal CalculateDiscount(CreditCard creditCard);); - 在
IPaymentMethod接口和实现类中新增接受访问的方法(比如decimal GetDiscount(IPaymentCalculationsVisitor visitor);); - 在
PaymentCalculationsVisitor中实现具体的计算逻辑。
这种方式能始终保持元素类的稳定,把所有变化的操作逻辑集中到访问者类中,完全符合访问者模式的设计初衷。
内容的提问来源于stack exchange,提问作者FredE
相关产品推荐
相关产品推荐

