写在前面
本文看一种行为型设计模式,访问者模式。
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