• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Stoop 431-visitor

on

  • 385 views

 

Statistics

Views

Total Views
385
Views on SlideShare
385
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Stoop 431-visitor Stoop 431-visitor Presentation Transcript

    • Visitor
      • Intent : Represent an operation to be performed on the elements of an object structure in a class separate from the elements themselves. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
      Visitor Intent
    • Visitor Possible Structure
      • Whenever you have a number of items on which you have to perform a number of actions
      • When you ‘decouple’ the actions from the items.
      • Examples:
        • the parse tree (ProgramNode) uses a visitor for the compilation (emitting code on CodeStream)
        • GraphicsContext is a visitor for VisualComponents, Geometrics, and some other ones (CharacterArray, ...)
        • Rendering documents
      When to use a Visitor
      • So all our problems are solved, no?
      • Well...
        • how to define it
        • when to use a visitor
        • control over item traversal
        • choosing the granularity of visitor methods
        • implementation tricks
      Applying the Visitor
      • Language to deal with arithmetic expressions.
      • It supports one kind of number, and has +, *, (, )
      • We want to evaluate expressions, and print them.
      Visitor Toy Example
    • Example
        • Evaluating
        • 1 + 1
          • gives = 2
        • 1 + (3 * 2)
            • gives 7
        • Printing
          • +1*32
    • Visitor Toy Example: ParseTree
    • Expressions creation
      • 1
          • ENumber value: 1
      • (3 * 2)
          • Times left: (ENumber value: 3) right: (ENumber value: 2)
      • 1 + (3 * 2)
          • Plus
            • left: (ENumber value: 1)
              • right: (Times left: (ENumber value: 3) right: (ENumber value: 2))
            • Of course in Smalltalk we can just extend Number so no
            • need of ENumber value:.....
      • Two solutions:
        • add methods for evaluating, printing, ... on Expression and its subclasses
        • create a Visitor, add the visit methods on Expression and its subclasses, and implement visitors for evaluation, printing, ...
      Implementing the Actions
    • Visitor Toy Example Solution 1
    • Expressions creation
        • (ENumber value: 1) evaluate
          • > 1
        • (Times left: (ENumber value: 3) right: (ENumber value: 2)) evaluate
          • > 6
        • (Plus left: (ENumber value: 1) right: (Times left: (ENumber value: 3) right: (ENumber value: 2))) evaluate
          • > 7
        • printing is not easy may need specific instance variables
        • adding it directly on Expression clutters Expression
          • may need to add instance variables that are not part of the tree
          • behavior of the printer are mixed with expressions
      Limits of the approach
    • Visitor Toy Example 2
    • Expressions creation
          • Evaluator evaluate: (ENumber value: 1)
            • > 1
          • Evaluator evaluate: (Times left: (ENumber value: 3) right: (ENumber value: 2))
            • > 6
          • Evaluator evaluate: (Plus left: (ENumber value: 1) right: (Times left: (ENumber value: 3) right: (ENumber value: 2)))
            • > 7
        • Evaluator>>evaluate: anExpression
        • ^ anExpression acceptVisitor: self
    • Evaluator
              • Evaluator>>visitNumber: aNumber
              • ^ aNumber value
            • Evaluator>>visitPlus: anExpression
            • |l r|
            • l := anExpression left acceptVisitor: self.
            • r := anExpression right acceptVisitor: self.
            • ^ l + r
            • Evaluator>>visitPlus: anExpression
              • |l r|
              • l := anExpression left acceptVisitor: self.
              • r := anExpression right acceptVisitor: self.
              • ^ l * r
    • Printer
              • Visitor subclass: #Printer
              • iv: ‘stream level’
              • Printer>>visitNumber: aNumber
              • stream nextPutAll: aNumber value asString
              • Printer>>visitPlus: anExpression
              • stream nextPutAll: ‘+’.
              • anExpression left acceptVisitor: self.
              • anExpression right acceptVisitor: self.
              • Printer>>visitPlus: anExpression
              • stream nextPutAll: ‘*’.
              • anExpression left acceptVisitor: self.
              • anExpression right acceptVisitor: self.
      • Smalltalk has class extensions:
        • method addition
        • method replacement
      • So ‘Decoupling’ actions from items can be done:
        • e.g., put all the printing methods together.
        • take care: works only for methods
        • makes it also really easy to package a visitor!
      • Note: this is a static solution!
      Smalltalk’s class extensions
      • Somewhere in the visitor, items are traversed.
      • Different places where the traversal can be implemented:
        • in the visitor
        • on the items hierarchy
      Controlling the traversal
    • Traversal on the Visitor
    • Traversal on the Items
      • Sometimes you can represent contextual information by having more specialized visit methods
      • So visitors have more information for implementing their operations
      Granularity of Visit Methods
        • doNode: is invoked from doVariables: and doSequence:temporaries:statements:
      Granularity of Visit Methods
      • Here doTemporaryVariable: provides the context for treating doVariable:
      Refined Granularity
      • You can implement it as we have shown before.
      • But notice the general structure of the methods!
      • This can be taken as advantage:
        • code can be generated for a visitor.
        • the method can be performed/invoked
      • But take care:
        • only works when there is a full correspondence.
        • can make the code hard to understand.
      Implementation Tricks
    • Using #perform:
      • Use a Visitor:
        • when the operations on items change a lot.
      • Do not use a visitor:
        • when the items you want to visit change a lot.
      • Question: But how do we know what to choose up-front?
      When to Use a Visitor