【Java中23种面试常考的设计模式之访问者模式(Visitor)---行为型模式】
知识回顾:
>
之前我们讲过的设计模式在这里呦:
【面试最常见的设计模式之单例模式】
【面试最常见的设计模式之工厂模式】
【Java中23种面试常考的设计模式之备忘录模式(Memento)---行为型模式】
【Java中23种面试常考的设计模式之观察者模式(Observer)---行为型模式】
【Java中23种面试常考的设计模式之模板模式(Template)---行为型模式】
【Java中23种面试常考的设计模式之状态模式(State)---行为型模式】
【Java中23种面试常考的设计模式之策略模式(Strategy)---行为型模式】
【Java中23种面试常考的设计模式之迭代器模式(Iterator)---行为型模式】
接下来我们要进行学习的是:【Java中23种面试常考的设计模式之访问者模式(Visitor)---行为型模式】。
访问者模式
访问者模式:使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。
通俗来说就是:不同的人对同一件事情有着不同的处理方式。
解决的问题
- 主要将数据结构与数据操作分离。
- 稳定的数据结构和易变的操作耦合问题。
生产开发中常用的使用场景
- XML文档解析器设计。
- 编译器的设计。
- 复杂集合对象的处理。
- (应用范围非常窄,了解即可)
访问者模式优点与缺点
优点
- 符合单一职责原则。
- 优秀的扩展性。
- 灵活性。
缺点
- 具体元素对访问者公布细节,违反了迪米特原则。
- 具体元素变更比较困难。
- 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
核心角色
Visitor接口:定义了某个状态下所有Element接口中具体实现类对应的执行规则
ConcreteVisitor1具体类:实现了Visitor接口,自己具体实现内容
ConcreteVisitor2具体类:实现了Visitor接口,自己具体实现内容
Element接口:定义了处理事情或者是执行方法的规则
ConcreteElementA具体类:实现了Element接口,实现了自己的内容
ConcreteElementB具体类:实现了Element接口,实现了自己的内容
ObjectStructure类:Element元素的数据集合,添加,删除,执行展示方法等等。。
UML类图
实现代码
我们实现这样一个栗子:
成功的男人后面有一个贤惠的女人
成功的女人后面有一个傻傻的男人
男生恋爱时:遇到不会的事儿也要装懂
女生恋爱时:遇到会的事儿也要装不懂
仔细思考一下我们会发现:人对应的Element接口,男人女人就是俩个具体实现类,成功和恋爱的状态就是Visitor,每个状态下对应的不同的是Element具体实现类的不同处理方式,由此对应的是俩个具体Visitor实现类,最后多个Element元素需要我们使用集合来存储。
Visitor接口
package com.visitor;
//遇到的一个状态(一般情况下:其定义的方法个数与Element实现类个数相等)
public interface Visitor{
void visitConcreteElementA(ConcreteElementA concreteElementA);
void visitConcreteElementB(ConcreteElementB concreteElementB);
}
ConcreteVisitor1具体类
package com.visitor;
//成功这个状态
public class ConcreteVisitor1 implements Visitor{
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
// TODO Auto-generated method stub
System.out.println("成功的男人后面有一个贤惠的女人");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
// TODO Auto-generated method stub
System.out.println("成功的女人后面有一个傻傻的男人");
}
}
ConcreteVisitor2具体类
package com.visitor;
//恋爱这个状态
public class ConcreteVisitor2 implements Visitor{
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
// TODO Auto-generated method stub
System.out.println("男生恋爱时:遇到不会的事儿也要装懂");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
// TODO Auto-generated method stub
System.out.println("女生恋爱时:遇到会的事儿也要装不懂");
}
}
Element接口
package com.visitor;
//人处理事情的方式
public interface Element {
void accept(Visitor visitor);
}
ConcreteElementA具体类
package com.visitor;
//男人处理事情的方式
public class ConcreteElementA implements Element{
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
visitor.visitConcreteElementA(this);
}
}
ConcreteElementB具体类
package com.visitor;
//女人处理事情的方式
public class ConcreteElementB implements Element{
@Override
public void accept(Visitor visitor) {
// TODO Auto-generated method stub
visitor.visitConcreteElementB(this);
}
}
ObjectStructure类
package com.visitor;
import java.util.ArrayList;
import java.util.List;
public class ObjectStructure{
private List<Element> list=new ArrayList<>();
public void addElement(Element element){
list.add(element);
}
public void removeElement(Element element){
list.remove(element);
}
public void accept(Visitor visitor){
for(Element e:list){
e.accept(visitor);
}
}
}
测试代码
package com.visitor;
public class Main {
public static void main(String[] args){
ObjectStructure objectStructure=new ObjectStructure();
objectStructure.addElement(new ConcreteElementA());
objectStructure.addElement(new ConcreteElementB());
ConcreteVisitor1 concreteVisitor1=new ConcreteVisitor1();
ConcreteVisitor2 concreteVisitor2=new ConcreteVisitor2();
objectStructure.accept(concreteVisitor1);
objectStructure.accept(concreteVisitor2);
}
}
运行结果展示:
好了,到这里【Java中23种面试常考的设计模式之访问者模式(Visitor)---行为型模式】就结束了,23种设计模式持续更新汇总中。