Lexi case study Part 2 - PowerPoint PPT Presentation

About This Presentation
Title:

Lexi case study Part 2

Description:

Traverse back and forth through list to undo and redo. Call Unexecute() when undoing, Execute() when redoing. Command class. Command class ... – PowerPoint PPT presentation

Number of Views:30
Avg rating:3.0/5.0
Slides: 27
Provided by: cec2
Category:
Tags: case | lexi | part | redoing | study

less

Transcript and Presenter's Notes

Title: Lexi case study Part 2


1
Lexi case study (Part 2)
  • Presentation by Matt Deckard

2
User Operations
  • Support different operations
  • Cut, copy, paste
  • Formatting
  • Printing
  • Etc.
  • Support different Uis
  • Menus
  • Buttons
  • Keyboard shortcuts
  • Etc.

3
User Operations
  • Avoid coupling operations and UIs
  • Use multiple UIs for single operations
  • Change UIs in the future
  • Avoid creating dependencies to classes operations
    are defined in
  • Undo and Redo
  • Want some, but not all operations to be undoable
  • Un-undoable operations
  • Saving
  • Creating new documents
  • Printing
  • Dont want arbitrary limit on levels of undo

4
User Operations
  • Encapsulate user operations
  • GUI menus are just glyphs that perform actions in
    response to user interaction
  • Create subclass of Glyph called MenuItem
  • But dont want to make each operation a subclass
    of MenuItem (avoid decoupling!)
  • Parameterize menu items by uper operations
  • How?

5
User Operations
  • How should user operations be parameterized?
  • Simple function call has drawbacks
  • Doesnt address undo/redo
  • Hard to associate state with function
  • Difficult to extend, reuse
  • Use objects instead
  • Can store state, implement undo/redo
  • Use inheritance to extend, reuse

6
Command class
  • Command abstract class representing user
    operation
  • Based on abstract method Execute()
  • Subclasses will implement Execute() according to
    the operation they represent
  • Subclasses can delegate parts of user operation
    to other objects
  • Command objects are treated uniformly by
    requestor
  • MenuItem will store instance of Command object to
    encapsulate its associated user operation

7
Command class
  • Undoability
  • Add abstract Unexecute() method
  • During Execute(), Commands will store whatever
    information they need to undo later
  • Add abstract Reversible() method
  • Returns true if and only if this Command is
    undoable
  • Allows Commands to determine undoability at
    runtime
  • i.e. redundant or vacuous Commands shouldnt be
    undoable
  • Command history
  • Need list of Commands to support multiple undos
  • Traverse back and forth through list to undo and
    redo
  • Call Unexecute() when undoing, Execute() when
    redoing

8
Command class
9
Command class
10
Command Pattern
  • Encapsulates a request (user operation)
  • Prescribes uniform interface for requests
  • Shields clients from requests implementation
  • Allows delegation of request to other objects
  • Provides centralized access to functionality
  • Allows to queue or log requests
  • Supports undo, redo
  • AKA Action, Transaction
  • Similar to functor (but not quite the same)

11
Command Pattern
  • Related patterns
  • Use with Composite and youve got macros!
  • Use with Memento to remember state (for undo)
  • Use Prototype to copy command before putting in
    undo list, to distinguish multiple invocations of
    same command

12
Spellchecking and Hyphenation
  • Textual analysis
  • Want to support multiple algorithms, addition of
    new ones in future
  • Avoid coupling to document structure
  • Add other types of analysis in future
  • i.e. search, word count, etc.
  • Two pieces
  • Accessing information to be analyzed
  • Performing the analysis

13
Accessing scattered information
  • Data access
  • Glyphs may be stored in different ways
  • Need mechanism to access all of them
  • Traversal
  • Different analyses may access Glyphs in different
    ways (i.e. forward vs. reverse search)
  • Issues
  • Only Glyphs know their data structure
  • Glyph interface shouldnt be biased toward one
    structure over another
  • i.e. using integer index biased us toward arrays
  • Want to provide multiple access and traversal
    methods

14
Accessing scattered information
  • One approach adding methods to Glyph
  • void First(Traversal) initializes specified
    traversal
  • void Next() advances to next Glyph in traversal
  • bool IsDone() reports if traversal is over
  • Glyph GetCurrent() accesses current glyph
  • Replaces Child()
  • void Insert(Glyph) inserts Glyph at current
    pos
  • Replaces Insert(Glyph, int)

15
Accessing scattered information
  • Issues with this approach
  • Must extend Traversal enumeration to support new
    traversals
  • Would also have to change lots of subclasses
  • Difficult to reuse mechanism for other object
    structures
  • Doesnt support multiple traversals in parallel

16
Iterator class
  • Better approach encapsulate access and traversal
  • Iterator
  • Abstract class
  • Defines interface for access and traversal
  • Subclass contains reference to structure it
    traverses
  • CreateIterator()
  • By default, will return NullIterator
  • Subclasses can override, based on their structure
  • Iterators can use CreateIterator() on their root
    glyphs to support different traversal

17
Iterator class
  • Example PreorderIterator
  • First()
  • Calls CreateIterator() on root
  • Calls First() on returned Iterator
  • Pushes Iterator onto stack
  • CurrentItem()
  • Calls CurrentItem() on Iterator at top of stack
  • Returns result
  • Next()
  • Calls CreateIterator() on top Iterator
  • Calls First() on returned Iterator
  • Pushes Iterator onto stack
  • Calls IsDone() on latest Iterator. If true, pops
    it off and repeats

18
Iterator class
19
Iterator Pattern
  • Abstracts traversal algorithm
  • Shields clients from internal structure of
    objects traversed
  • Gain flexability, usability
  • Easy to extend
  • Easy to reuse by parameterizing object type
  • Can perform multiple traversals in parallel

20
Performing the analysis
  • Want to distinguish analysis from traversal
  • Flexibility, reusability
  • Different analyses might require same traversal
  • Want to distinguish different types of glyphs
  • Different analyses consider different glyphs
  • Could abstract in Glyph, have subclasses
    implement
  • Drawbacks to this approach
  • Have to change multiple subclasses
  • Obscures basic glyph interface

21
Performing the analysis
  • Encapsulate the analysis
  • Create analysis classes
  • For now, lets consider a SpellChecker class
  • Iterator has instance of SpellChecker
  • Uses SpellChecker instance as it traverses
  • SpellChecker accumulates information as it is used

22
Performing the analysis
  • How to distinguish glyphs?
  • SpellChecker treats different glyph types
    differently
  • Dont want to resort to type tests or casting
    (gross)
  • Instead, have the glyph object tell SpellChecker
    to check it
  • Glyph has abstract CheckMe() method
  • SpellChecker has methods for every glyph
    subclass, i.e. CheckCharacter(), CheckRow(),
    CheckImage(), etc.
  • Glyph sublcasses will override CheckMe() to call
    the appropriate method in SpellChecker

23
Performing the analysis
24
Performing the analysis
  • Adding new analyzers
  • Will be difficult if we define them as separate
    classes
  • Instead, abstract it as a Visitor class
  • CheckMe() becomes the Accept() method
  • Takes any Visitor as parameter, so dont have to
    touch glyph subclasses when adding new analyzers
  • CheckCharacter(), etc become the Visit() method
  • Overloaded, takes visited subclass as parameter
  • Need one for every subclass that implements
    Accept()

25
Visitor Pattern
  • Can be applied to any object structure
  • Visitees neednt have common parent class
  • Tradeoff
  • When you add Visitors you dont have to update
    object structure, BUT
  • When you add subclasses to object structure, you
    DO have to update your Visitor classes
  • Sometimes can provide default do nothing
    operation in Visitor
  • Helps avoid polluting classes with many
    operations
  • Helps to separate groups of common operations
  • Can accumulate state as they visit elements
  • Sometimes compromises encapsulation of visitee
  • elements

26
Summary
  • Needed to support different user operations
  • Encapsulate the concept that varies (Command)
  • Needed to support different methods of accessing
    and traversing data
  • Encapsulate the concept that varies (Iterator)
  • Needed to support different analysis algorithms
  • Encapsulate the concept that varies (Visitor)
  • (Are we seeing a pattern here?)
Write a Comment
User Comments (0)
About PowerShow.com