Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.03 KB | None | 0 0
  1. // Element base class
  2. public abstract class Element {
  3. // I am returning an Element here (different from a "normal" GoF implementation)
  4. internal abstract Element Accept(IVisitor visitor);
  5. }
  6.  
  7. // Visitor base class
  8. public abstract class VisitorBase: IVisitor
  9. {
  10. // Again, return an Element
  11. // This is so that each visitor can choose to return a different type
  12. // than the visited Element
  13. public virtual Element Visit(Element element)
  14. {
  15. element = element.Accept(this);
  16. return element;
  17. }
  18.  
  19. // Another departure from vanilla visitor: Visit just this element
  20. // (and don't recurse)
  21. public virtual Element VisitNonRecursive(Element element)
  22. {
  23. return element;
  24. }
  25.  
  26. // These can be individually overridden, and I have added these for transforming
  27. // one type of Element into another
  28. public virtual Element VisitNonRecursive(LeafElementA leafElementA)
  29. {
  30. return VisitNonRecursive(leafElementA as Element);
  31. }
  32.  
  33. public virtual Element VisitNonRecursive(LeafElementB leafElementB)
  34. {
  35. return VisitNonRecursive(leafElementB as Element);
  36. }
  37.  
  38. // ...similar methods for the other elements (removed to reduce clutter in the snippet)
  39. }
  40.  
  41. public class LeafElementA : Element
  42. {
  43. internal override Element Accept(IVisitor visitor)
  44. {
  45. return visitor.VisitNonRecursive(this);
  46. }
  47. }
  48.  
  49. // Implementation of Element that contains multiple other Elements
  50. public class CompositeElement : Element
  51. {
  52. public CompositeElement(params Element[] containedElements)
  53. {
  54. ContainedElements = containedElements.ToList();
  55. }
  56.  
  57. public ICollection<Element> ContainedElements { get; private set; }
  58.  
  59. internal override Element Accept(IVisitor visitor)
  60. {
  61. ContainedElements = ContainedElements
  62. // Recursively visit each child
  63. .Select(visitor.Visit)
  64. .ToList();
  65.  
  66. // And non-recursively visit this
  67. return visitor.VisitNonRecursive(this);
  68. }
  69. }
  70.  
  71. // Implementation of Element that contains exactly two other Elements
  72. public class BinaryElement : Element
  73. {
  74. public BinaryElement(Element left, Element right)
  75. {
  76. Left = left;
  77. Right = right;
  78. }
  79.  
  80. public Element Left { get; private set; }
  81.  
  82. public Element Right { get; private set; }
  83.  
  84. internal override Element Accept(IVisitor visitor)
  85. {
  86. // Recursively visit the children
  87. Left = visitor.Visit(Left);
  88. Right = visitor.Visit(Right);
  89.  
  90. // And non-recursively visit this
  91. return visitor.VisitNonRecursive(this);
  92. }
  93. }
  94.  
  95. // Implementation of Visitor that adds a LeafElementA to any composite element
  96. public class AddOneMoreVisitor : VisitorBase
  97. {
  98. public override Element VisitNonRecursive(MultiCompositeElement multiCompositeElement)
  99. {
  100. multiCompositeElement.ContainedElements.Add(new LeafElementA());
  101. return multiCompositeElement;
  102. }
  103.  
  104. public override Element VisitNonRecursive(BinaryCompositeElement binaryCompositeElement)
  105. {
  106. // Here we are able to change the returned type from the visitor
  107. var result = new MultiCompositeElement(
  108. binaryCompositeElement.Left,
  109. binaryCompositeElement.Right,
  110. new LeafElementA()
  111. );
  112. return result;
  113. }
  114.  
  115. // The rest of the recursion-based visiting can be delegated to the base
  116. }
  117.  
  118. internal abstract Element Transform(ITransformer transformer);
  119.  
  120. new BinaryElement(null, null).Accept(...)
  121.  
  122. interface IVisitor
  123. {
  124. //removed from interface
  125. //(you can still have this method as `protected virtual` in base implementation)
  126. //Element Visit(Element element);
  127.  
  128. Element Visit(BinaryElement element);
  129. Element Visit(CompositeElement element);
  130. //etc...
  131. }
  132.  
  133. interface IVisitor
  134. {
  135. Element Visit(Element element);
  136.  
  137. //removed from interface
  138. //(you can still have those methods as `protected virtual` in base implementation)
  139. //Element Visit(BinaryElement element);
  140. //Element Visit(CompositeElement element);
  141. }
  142.  
  143. public virtual Element Visit(Element element)
  144. {
  145. element = element.Accept(this);
  146. return element;
  147. }
  148.  
  149. public virtual Element Invite(Element element)
  150. {
  151. element = element.Accept(this);
  152. return element;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement