设计模式 - 访问者模式
访问者模式:在数据结构与用户之间,提供一层visitor封装,用户通过visitor对数据结构进行访问(类似存储过程)
核心:visitor封装对数据结构的操作,用户通过visitor对数据结构进行访问(每一个visitor实现子类都对应了一种访问方式)
角色:
-
IVisitor: 提供访问元素的抽象接口 - 需提供所有ConcreteElement对象的visit访问方法
-
ConcreteVisitor: IVisitor的实现子类,其内定义针对每一种ConcreteElement的具体操作(访问方式)
-
IElement/ConcreteElement: 元素,可能存在IElement的多种实现。
-
ObjectStructure: 数据结构(数据表),维护所有的IElement实例,并提供接受IVisitor,以遍历访问所有的element。
PS: ①由ObjectStructure维护所有Element的集合,②用户需通过IVisitor实现对ObjectStructure中元素的访问
general
IVisitor
// IVisitor接口中需定义对所有类型元素的访问方法
public interface IVisitor {
void visit(ElementA element);
void visit(ElementB element);
}
// 每一个Visitor都代表一种对数据集合的访问模式。
public class Visitor1 implements IVisitor{
public void visit(ElementA element) { System.out.println(element.getId() + " - core:" + element.getCore() );}
public void visit(ElementB element) { System.out.println(element.getId() + " - spend:" + element.getSpend() );}
}
ObjectStructure
// 数据集合,维护数据集合相关的操作,以及提供一个为visitor访问所有element的方法
public class ElementContainer {
private ArrayList<IElement> elements = new ArrayList<>();
public void addElement(IElement element){ ... }
// 使所有的element接受visitor的访问
public void show(IVisitor visitor){
for(IElement element : elements){
element.accept(visitor);
}
}
}
IElement
// IElement接口中声明接受IVisitor访问的方法
public interface IElement {
void accept(IVisitor visitor);
}
// IElement实现子类,在编译时,根据方法重载可确定调用IElement的哪个方法,在运行时,根据继承链找到具体的子类实现方法。
public class ElementA implements IElement{
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
方法重写与重载
public class Dispatch {
public static void main(String[] args) {
// 方法重载,静态分派 -- 编译阶段即可确定调用方法
Dispatch dispatch = new Dispatch();
dispatch.print(100);
dispatch.print("100");
// 方法重写,动态分派 -- 只有运行过程中根据对象的实际类型确定调用方法
IPerson person = dispatch.createPerson();
person.getSex(); // may: Woman.getSex() or Man.getSex()
}
private void print(String str){
System.out.println("Str is " + str);
};
private void print(Integer i){
System.out.println("Num is " + i);
}
}
欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友
-- 星河有灿灿,愿与之辉