设计模式之访问者模式

写在前面

本文看一种行为型设计模式,访问者模式。

1:介绍

1.1:什么时候使用访问者设计模式

当一个对象(objectstructure),有固定的的几个元素(element),并且当这个对象要完成不同的任务(Visitor)时,固定的这几个元素在任务中承担的职责也不同,当满足这种场景时就可以考虑使用访问者设计模式。

1.2:UML类图

原型设计模式,包含如下元素:

1:objectstructure
    拥有固定元素个数的对象
2:Element
    objectstructure中的元素,定义了accept(visitor)方法把自己交给访问者访问
3:ConcreteElement
    具体元素类
3:Visitor
    访问者,其实就是对象要完成的具体任务

2:实例

源码

2.1:场景

王老板,开了一个公司,只有一个开发小草莓,一个测试小葡萄,一个hr小酸梅,王老板为了省钱,只有这三个员工,并且王老板开了两个业务线,分别做对标抖音的短视频APP和对标微信的聊天APP,开发小草莓,测试小葡萄,hr小酸梅,在不同的产品中承担了不同的角色。此场景和访问者设计模式元素的对应关系如下:

Element:开发小草莓,测试小葡萄,hr小酸梅
objectstructure:王老板的公司,有三个element,开发小草莓,测试小葡萄,hr小酸梅
Visitor:短视频APP,微信的聊天APP

2.2:程序

  • 定义ELement
java 复制代码
public interface CorporateSlaveElement {
    // 接受不同访问者的访问(相当于是接受不同的任务,并在任务中承担不同的角色)
    void accept(CorporateSlaveVisitor visitor);
}
  • ConcreteElement
    hr小酸梅:
java 复制代码
public class HumanSourceElement implements CorporateSlaveElement {

    private String name;

    public HumanSourceElement(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void accept(CorporateSlaveVisitor visitor) {
        visitor.visit(this);
    }
}

开发小草莓:

java 复制代码
public class ProgrammerElement implements CorporateSlaveElement {
    private String name;

    public ProgrammerElement(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void accept(CorporateSlaveVisitor visitor) {
        visitor.visit(this);
    }
}

测试小葡萄:

java 复制代码
public class TesterElement implements CorporateSlaveElement {

    private String name;

    public TesterElement(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void accept(CorporateSlaveVisitor visitor) {
        visitor.visit(this);
    }
}
  • 定义visitor
java 复制代码
public interface CorporateSlaveVisitor {
    void visit(ProgrammerElement programmer);

    void visit(HumanSourceElement humanSource);

    void visit(TesterElement tester);
}

即让不同的任务能够访问Element,并使用其在自己的任务中完成特定的任务。接下定义具体访问者,对标抖音的短视频APP和对标微信的聊天APP:

java 复制代码
public class LiveAppVisitor implements CorporateSlaveVisitor {
    @Override
    public void visit(ProgrammerElement programmer) {
        System.out.println(programmer.getName() + " 在短视频中发挥作用了");
    }

    @Override
    public void visit(HumanSourceElement humanSource) {
        System.out.println(humanSource.getName() + " 在短视频中发挥作用了");
    }

    @Override
    public void visit(TesterElement tester) {
        System.out.println(tester.getName() + " 在短视频中发挥作用了");
    }
}

public class SocialAppVisitor implements CorporateSlaveVisitor {
    @Override
    public void visit(ProgrammerElement programmer) {
        System.out.println(programmer.getName() + " 在社交应用中发挥作用了");
    }

    @Override
    public void visit(HumanSourceElement humanSource) {
        System.out.println(humanSource.getName() + " 在社交应用中发挥作用了");
    }

    @Override
    public void visit(TesterElement tester) {
        System.out.println(tester.getName() + " 在社交应用中发挥作用了");
    }
}
  • objectstructure
    即王老板的公司,拥有一个开发小草莓,一个测试小葡萄,一个hr小酸梅,三个元素:
java 复制代码
public class BigHuYouCompany {
    private static List<CorporateSlaveElement> employee = new ArrayList() {
        {
            add(new ProgrammerElement("开发小草莓"));
            add(new HumanSourceElement("hr小酸梅"));
            add(new TesterElement("测试小葡萄"));
        }
    };
    private CorporateSlaveVisitor visitor;
//    public BigHuYouCompany() {
//        employee.add(new ProgrammerElement("开发小草莓"));
//        employee.add(new HumanSourceElement("hr小酸梅"));
//        employee.add(new TesterElement("测试小葡萄"));
//    }

    public BigHuYouCompany(CorporateSlaveVisitor visitor) {
        this.visitor = visitor;
    }

//    public void startProject(CorporateSlaveVisitor visitor){
    public void startProject(){
        for (CorporateSlaveElement slave : employee) {
            slave.accept(visitor);
        }
    }
}
  • 客户端类
java 复制代码
 @Test
public void startProject() {
    System.out.println("-----------------启动社交APP项目--------------------");
    BigHuYouCompany bigHuYouDoSocialApp= new BigHuYouCompany(new SocialAppVisitor());
    //可以很轻松的更换Visitor,但是要求BigHuYouCompany的结构稳定
    bigHuYouDoSocialApp.startProject();
    System.out.println("-----------------启动短视频APP项目--------------------");
    BigHuYouCompany liveAppVisitor= new BigHuYouCompany(new LiveAppVisitor());
    liveAppVisitor.startProject();
}

运行:

-----------------启动社交APP项目--------------------
开发小草莓 在社交应用中发挥作用了
hr小酸梅 在社交应用中发挥作用了
测试小葡萄 在社交应用中发挥作用了
-----------------启动短视频APP项目--------------------
开发小草莓 在短视频中发挥作用了
hr小酸梅 在短视频中发挥作用了
测试小葡萄 在短视频中发挥作用了

Process finished with exit code 0

写在后面

参考文章列表

秒懂设计模式之访问者模式(Visitor Pattern)

相关推荐
暗黑起源喵2 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
wrx繁星点点9 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干11 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨11 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉20 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点20 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰20 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus21 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵21 小时前
设计模式-迭代器
设计模式
lexusv8ls600h1 天前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式