访问者模式
1.简单介绍
- 访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,可以在不改变结构的前提下定义新的操作(作用于这些元素)
- 访问者模式主要是将数据结构和数据的操作进行分离,解决了数据结构和操作耦合性的问题
- 访问者模式的基本工作原理是: 在被访问的类里提供一个对外接待访问者的方法
void accept(Visitor visitor)
2.访问者中的角色
- Visitor 抽象访问者,为该对象结构中的ConcreteElement的每一个类声明一个访问操作
- ConcreteVisitor 具体的访问者,实现每个有Visitor声明的操作
- Element: 定义了一个accept操作,可以接受访问者对象
- ConcreteElement: 具体的待访问类,实现accept方法(内部聚合访问者)
- ObjectStructure访问元素的集合(多个Element),便于统一规划
3.访问者模式的结构图
4.实现简单的访问者模式代码
import com.liz.GOF23.visitor.relearn.visitor.Visitor;
//!!!被访问类的接口
//抽象元素(内部有accept方法用于接收访问者)
public interface Element {
void accept(Visitor visitor);
}
//!!!具体被访问类A
public class ConcreteElemA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//加入额外操作
public String operationA(){
return "具体元素A的操作";
}
}
//!!!具体被访问类B
public class ConcreteElemB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//加入额外操作
public String operationB(){
return "具体元素B的操作";
}
}
//!!!抽象访问者
public interface Visitor {
//需要体现出个性 而不是统一化操作
default void visit(ConcreteElemA elementA){}
default void visit(ConcreteElemB elementB){}
}
//!!!具体访问者A
public class ConcreteVisitorA implements Visitor {
@Override
public void visit(ConcreteElemA element) {
System.out.println("具体访问者A访问:"+element.operationA());
}
}
//!!!具体访问者B
public class ConcreteVisitorB implements Visitor {
@Override
public void visit(ConcreteElemB elementB) {
System.out.println("具体访问者B访问:"+elementB.operationB());
}
}
//访问元素的集合
public class ObjectStructure {
private List<Element> list=new ArrayList<Element>();
public void accept(Visitor visitor){
for (Element element : list) {
//数据和visitor之间进行适应
element.accept(visitor);
}
}
public void add(Element element){
list.add(element);
}
public void remove(Element element){
list.remove(element);
}
}
//Client
public class Client {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElemA());
os.add(new ConcreteElemB());
Visitor visitorA = new ConcreteVisitorA();
os.accept(visitorA);
System.out.println("===============");
Visitor visitorB = new ConcreteVisitorB();
os.accept(visitorB);
}
}
运行结果:
5.访问者模式细节:
-
访问者模式的应用场景: 需要对一个具体结构的对象进行很多不同的操作(这些操作彼此之间没有关联),同时需要避免让这些操作影响对象的类。可以采用访问者模式解决
-
优点
* 扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。
* 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。
* 灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。
*符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。 -
缺点
- 增加新的元素类十分困难,需要在具体访问者类中增加相应的操作,违反了开闭原则。
- 破坏了封装性,访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
- 违反了依赖倒置原则,访问者模式依赖了具体类,而没有依赖抽象类。
参考资料:http://c.biancheng.net/view/1397.html
来源:CSDN
作者:君尔
链接:https://blog.csdn.net/Lzinner/article/details/104750991