设计模式:访问者模式

文章目录

定义

访问者模式(Visitor Pattern)是一种将算法与对象结构分离的设计模式。这种模式中,可以在不修改已有程序结构的前提下,通过添加额外的"访问者"来定义作用于对象结构中各元素的新操作。它主要解决的是稳定的数据结构和易变的操作耦合问题。

应用场景

  • 当一个对象结构包含很多类对象,且这些类的对象对应的操作经常变化时。
  • 当需要对一个复杂的对象结构进行一些不依赖于对象具体类型的操作时。
  • 当需要对对象结构中的对象进行很多不同且不相关的操作,而需要避免让这些操作"污染"对象的类时。

示例代码

假设有一个电子商务系统,需要对不同类型的用户(如普通用户和VIP用户)进行不同的促销活动。

访问者接口 和具体的访问者实现

java 复制代码
interface Visitor {
    void visit(NormalUser user);
    void visit(VIPUser user);
}

class PromotionVisitor implements Visitor {
    @Override
    public void visit(NormalUser user) {
        System.out.println("给普通用户发送优惠券");
    }

    @Override
    public void visit(VIPUser user) {
        System.out.println("给VIP用户发送优惠券和积分");
    }
}

用户类接受访问的接口

java 复制代码
interface User {
    void accept(Visitor visitor);
}

class NormalUser implements User {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class VIPUser implements User {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

客户端代码

java 复制代码
public class Client {
    public static void main(String[] args) {
        List<User> users = Arrays.asList(new NormalUser(), new VIPUser());
        Visitor promotion = new PromotionVisitor();
        
        for (User user : users) {
            user.accept(promotion);
        }
    }
}

反例

当对象结构非常稳定,几乎不会新增元素类型,同时操作经常变化时,使用访问者模式是合适的。如果对象结构经常变化,则每次新增类型都需要修改访问者接口和所有实现类,这违背了开闭原则,此时应考虑其他设计模式。

原则间的权衡与冲突

  • 开闭原则:访问者模式支持在不修改已有对象结构的情况下,向已有对象结构中添加新操作,符合开闭原则。但如果需要添加新的元素类,就需要修改访问者接口及其所有实现,这违背了开闭原则。
  • 单一职责原则:访问者模式允许将操作逻辑从对象结构中分离出来,每个访问者执行特定的操作,符合单一职责原则。

设计模式的局限性

  • 增加新的元素类比较困难,每添加一个新的元素类,都要在Visitor接口中添加一个新的访问操作,并在所有的访问者实现类中实现该操作,这使得系统变得复杂。
  • 访问者模式使得对象结构的修改变得困难,因为访问者依赖于对象结构中元素的具体类。

总结与建议

访问者模式适用于对象结构相对稳定,而操作易变的场景。它使得增加新操作变得简单,但增加新的元素类较为复杂。在使用访问者模式时,应该权衡其带来的灵活性和可能的复杂性。在对象结构频繁变化的场景下,应考虑其他设计模式。

相关推荐
willow2 天前
Axios由浅入深
设计模式·axios
七月丶4 天前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞4 天前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼4 天前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟5 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder5 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室5 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦6 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo9 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式