lexi case study (part 2)
DESCRIPTION
Lexi case study (Part 2). Presentation by Matt Deckard. User Operations. Support different operations Cut, copy, paste Formatting Printing Etc. Support different Uis Menus Buttons Keyboard shortcuts Etc. User Operations. Avoid coupling operations and UIs - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/1.jpg)
Lexi case study (Part 2)
Presentation by Matt Deckard
![Page 2: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/2.jpg)
User Operations Support different operations
Cut, copy, paste Formatting Printing Etc.
Support different Uis Menus Buttons Keyboard shortcuts Etc.
![Page 3: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/3.jpg)
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
Don’t want arbitrary limit on levels of undo
![Page 4: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/4.jpg)
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 don’t want to make each operation a subclass
of MenuItem (avoid decoupling!) Parameterize menu items by uper operations How?
![Page 5: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/5.jpg)
User Operations How should user operations be
parameterized? Simple function call has drawbacks:
Doesn’t 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
![Page 6: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/6.jpg)
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
![Page 7: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/7.jpg)
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 shouldn’t 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
![Page 8: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/8.jpg)
Command class
![Page 9: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/9.jpg)
Command class
![Page 10: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/10.jpg)
Command Pattern Encapsulates a request (user operation) Prescribes uniform interface for requests Shields clients from request’s 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)
![Page 11: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/11.jpg)
Command Pattern Related patterns
Use with Composite and you’ve 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
![Page 12: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/12.jpg)
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
![Page 13: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/13.jpg)
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 shouldn’t be biased toward one
structure over another i.e. using integer index biased us toward arrays
Want to provide multiple access and traversal methods
![Page 14: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/14.jpg)
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)
![Page 15: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/15.jpg)
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 Doesn’t support multiple traversals in parallel
![Page 16: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/16.jpg)
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
![Page 17: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/17.jpg)
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
![Page 18: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/18.jpg)
Iterator class
![Page 19: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/19.jpg)
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
![Page 20: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/20.jpg)
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
![Page 21: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/21.jpg)
Performing the analysis Encapsulate the analysis
Create analysis classes For now, let’s consider a SpellChecker class
Iterator has instance of SpellChecker Uses SpellChecker instance as it traverses SpellChecker accumulates information as it is
used
![Page 22: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/22.jpg)
Performing the analysis How to distinguish glyphs?
SpellChecker treats different glyph types differently
Don’t 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
![Page 23: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/23.jpg)
Performing the analysis
![Page 24: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/24.jpg)
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 don’t 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()
![Page 25: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/25.jpg)
Visitor Pattern Can be applied to any object structure Visitees needn’t have common parent class Tradeoff:
When you add Visitors you don’t 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
![Page 26: Lexi case study (Part 2)](https://reader036.vdocument.in/reader036/viewer/2022062222/56815d34550346895dcb305d/html5/thumbnails/26.jpg)
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?)