访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构(Element)进行分离,数据结构的类只需要提供对"访问者"开放的接口(API),而对元素的具体处理则作交给访问者(Visitor)负责。
访问者模式中的角色:
Visitor:表示访问者的抽象类,用于声明对数据结构中xxx元素访问的visit(xxx)方法。
ConcreteVisitor:表示具体的访问者,继承Visitor并对其声明的抽象方法提供具体实现。
Element:表示元素的抽象类,即访问者实际要访问的对象,Element角色需要对访问者提供一个开放的接口,即accept方法,该方法的参数就是Visitor角色。
ConcreteElement:表示具体的元素,提供accept方法的实现。
ObjectStructure:负责处理Element元素的集合,即表示数据结构的类。
类图:
Element.m
classdef Element < handle & matlab.mixin.Heterogeneous methods(Abstract) accept(~,~); end end
ElementA.m
classdef ElementA < Element methods function accept(obj,visitor) visitor.visitElementA(obj); end function operationA(~) disp("this is OperationA") end end end
ElementB.m
classdef ElementB < Element methods function accept(obj,visitor) visitor.visitElementB(obj); end function operationB(~) disp("this is OperationB") end end end
Visitor.m
classdef Visitor < handle methods(Abstract) visitElementA(~,~); visitElementB(~,~); end end
ConcreteVisitorA.m
classdef ConcreteVisitorA < Visitor methods function visitElementA(~,element) disp("ConcreteVisitorA 访问 ElementA"); element.operationA(); end function visitElementB(~,element) disp("ConcreteVisitorA 访问 ElementB"); element.operationB(); end end end
ConcreteVisitorB.m
classdef ConcreteVisitorB < Visitor methods function visitElementA(~,element) disp("ConcreteVisitorB 访问 ElementA"); element.operationA(); end function visitElementB(~,element) disp("ConcreteVisitorB 访问 ElementB"); element.operationB(); end end end
ObjectStructure.m
classdef ObjectStructure < handle properties elements = Element.empty(); end methods function handleRequest(obj,visitor) for i = 1:length(obj.elements) obj.elements(i).accept(visitor); end end function addElement(obj,ele) obj.elements(end + 1) = ele; end end end
测试代码:
os = ObjectStructure(); eleA = ElementA(); eleB = ElementB(); os.addElement(eleA); os.addElement(eleB); visitor = ConcreteVisitorA(); os.handleRequest(visitor);
参考资料:
https://blog.csdn.net/iluojie/article/details/80382901
https://blog.csdn.net/SomeoneMH/article/details/80591429