《GOF设计模式》—访问者(VISITOR)—Delphi源码示例:访问者接口

示例:访问者接口
说明:
(1)、定义
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

(2)、结构

clip_image002


访问者
Visitor(访问者):为该对象结构中ConcreteElement的每一个类声明一个Visit操作。该操作的名字和特征标识了发送Visit请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
ConcreteVisitor(具体访问者):实现每个由Visitor声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。
对象
Element(元素):定义一个Accept操作,它以一个访问者为参数。
ConcreteElement(具体元素):实现Accept操作,该操作以一个访问者为参数。
ObjectStructure(对象结构):能枚举它的元素。可以提供一个高层的接口以允许该访问者访问它的元素。可以是一个复合(参见Composite)或是一个集合,如一个列表或一个无序集合。

代码:
unit uVisitor;

interface

uses
    Dialogs, Contnrs;

type
    TVisitor = class;

    TElement = class
    public
        procedure Accept(AVisitor: TVisitor); virtual; abstract;
    end;
    TConcreteElementA = class(TElement)
    public
        procedure Accept(AVisitor: TVisitor); override;
        procedure OperationA;
    end;
    TConcreteElementB = class(TElement)
    public
        procedure Accept(AVisitor: TVisitor); override;
        procedure OperationB;
    end;
    TObjectStructure = class(TObjectList)
    private
        function GetItems(Index: Integer): TElement;
    public
        procedure Accept(AVisitor: TVisitor);
        //---
        property Items[Index: Integer]: TElement read GetItems;
    end;
    TVisitor = class
    public
        procedure VisitConcreteElementA(AElement: TConcreteElementA); virtual; abstract;
        procedure VisitConcreteElementB(AElement: TConcreteElementB); virtual; abstract;
    end;
    TConcreteVisitor1 = class(TVisitor)
    public
        procedure VisitConcreteElementA(AElement: TConcreteElementA); override;
        procedure VisitConcreteElementB(AElement: TConcreteElementB); override;
    end;
    TConcreteVisitor2 = class(TVisitor)
    public
        procedure VisitConcreteElementA(AElement: TConcreteElementA); override;
        procedure VisitConcreteElementB(AElement: TConcreteElementB); override;
    end;

procedure Test;

implementation

procedure Test;
var
    AStructure: TObjectStructure;
    AVisitor: TVisitor;
begin
    AStructure := TObjectStructure.Create;
    AVisitor := TConcreteVisitor1.Create;
    try
        with AStructure do
        begin
            Add(TConcreteElementA.Create);
            Add(TConcreteElementB.Create);
            //---
            Accept(AVisitor);
        end;
    finally
        AVisitor.Free;
        AStructure.Free;
    end;
end;

procedure TConcreteElementA.Accept(AVisitor: TVisitor);
begin
    AVisitor.VisitConcreteElementA(Self);
end;

procedure TConcreteElementA.OperationA;
begin
    ShowMessage('A');
end;

procedure TConcreteElementB.Accept(AVisitor: TVisitor);
begin
    AVisitor.VisitConcreteElementB(Self);
end;

procedure TConcreteElementB.OperationB;
begin
    ShowMessage('B');
end;

procedure TConcreteVisitor1.VisitConcreteElementA(AElement: TConcreteElementA);
begin
    AElement.OperationA;
end;

procedure TConcreteVisitor1.VisitConcreteElementB(AElement: TConcreteElementB);
begin
    AElement.OperationB;
end;

procedure TConcreteVisitor2.VisitConcreteElementA(AElement: TConcreteElementA);
begin
    AElement.OperationA;
    AElement.OperationA;
end;

procedure TConcreteVisitor2.VisitConcreteElementB(AElement: TConcreteElementB);
begin
    AElement.OperationB;
    AElement.OperationB;
end;

procedure TObjectStructure.Accept(AVisitor: TVisitor);
var
    i: Integer;
begin
    for i := 0 to Self.Count - 1 do
        Self.Items[i].Accept(AVisitor);
end;

function TObjectStructure.GetItems(Index: Integer): TElement;
begin
    Result := TElement(inherited Items[Index]);
end;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值