Now we can write a visitor that just counts the shapes visited:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
unit uCounterVisitorIntf; interface uses uShapeBase; type TShapeVisitorCounter = class(TShapeVisitor, IAbstractShapeVisitor) private FCounter: Integer; public procedure VisitAbstractShape(Instance: TAbstractShape); property Counter: Integer read FCounter write FCounter; end; implementation procedure TShapeVisitorCounter.VisitAbstractShape(Instance: TAbstractShape); begin Inc(FCounter); end; end. |
Pretty easy and effective, isn’t it?
But there is still some drawback, as the visitor is limited to visit TAbstractShape and its descendants. What if we have other classes to visit that don’t fit in this inheritance scheme? Can’t we find a more general approach? Here it is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
interface uses Classes, SysUtils; type IVisited = interface; IVisitor = interface ['{4B6D36B4-BF62-420E-A85E-F16BB135C6A4}'] procedure Visit(Instance: IVisited); end; IVisited = interface ['{BCA80F82-4C43-4266-AB5D-C234668929A6}'] procedure Accept(Visitor: IVisitor); end; type TVisitor = class(TInterfacedPersistent, IVisitor) public procedure Visit(Instance: IVisited); virtual; end; implementation procedure TVisitor.Visit(Instance: IVisited); begin Instance.Accept(Self); end; end. |
With this TAbstractShape or any other class to be visited has to implement IVisited and we are done.
More in Part 4…