訪問者(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);
visitor = ConcreteVisitorB();
os.handleRequest(visitor);
運行結果:
參考資料: