设计模式之访问者模式

写在前面

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

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)

相关推荐
闲人一枚(学习中)23 分钟前
设计模式-创建型-抽象工厂模式
设计模式·抽象工厂模式
小白不太白9503 小时前
设计模式之 观察者模式
观察者模式·设计模式
小白不太白9504 小时前
设计模式之 责任链模式
python·设计模式·责任链模式
吾与谁归in4 小时前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式
吾与谁归in4 小时前
【C#设计模式(14)——责任链模式( Chain-of-responsibility Pattern)】
设计模式·c#·责任链模式
闲人一枚(学习中)4 小时前
设计模式-创建型-原型模式
设计模式
Iced_Sheep5 小时前
干掉 if else 之策略模式
后端·设计模式
哪 吒12 小时前
最简单的设计模式,抽象工厂模式,是否属于过度设计?
设计模式·抽象工厂模式
Theodore_102212 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
转世成为计算机大神15 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式