Download presentation
Presentation is loading. Please wait.
1
Case Study 1: Designing a Document Editor
Lesson 2: Case Study 1: Designing a Document Editor Object-Oriented Creational Paradigm Shift, Inc. Software Factory Behavioral Structural Design Patterns
2
Lesson Objectives Present a complete and a real case study: designing a document editor Show how to use design patterns in each component of the document editor Understand the document editor’s design issues
3
The Application “What-you-see-is-what-you-get,” or WYSIWYG, is a touted feature of contemporary application software called Lexi WYSIWYG user interfaces let users work with text and graphics in their most familiar form A WYSIWYG representation of the document occupies the large rectangle area in the center The document can mix text and graphics freely in a variety of formatting styles Surrounding the document are the usual pull-down menus and scroll bars plus a collection of page icons for jumping to a particular page in the document
4
Lexi’s Design Issues Document Structure Formatting
Embellishing the User Interface Supporting Multiple Look-and-Feel Standards Supporting Multiple Window Systems User Operations Spell Checking and Hyphenation
5
Document Structure Goals Recursive Composition Glyphs Design Patterns: Composite Pattern
6
Document Structure: Goals & Constraints
Maintaining the document’s physical structure Generating and presenting the document visually Mapping positions in the visual rendition to elements in the internal representation Using one set of formatting and manipulation mechanisms to deal with both text and graphics
7
Document Structure: Recursive Composition
Object Structure for Recursive Composition composite row Q q composite (column) composite (row) composite (row) Recursive Composition of text and graphics q Q space Recursive composition is a common way to represent hierarchically structured information by building increasingly complex elements out of simpler ones.
8
Document Structure: Glyphs
A Glyph is an abstract class. Its subclasses are specialized to support different graphical elements, both primitive (characters and images) and structural (rows and columns). Glyphs’ responsibilities: They know 1. How to draw themselves 2. The space they occupy 3. Their children and parent 4. A low-level presentation for themselves
9
Document Structure: Composite Pattern
Recursive composition can be used to represent potentially complex, hierarchical structure Programming languages can’t express this concept directly Composite pattern is used to document the recursive composition technique as it manifests itself in object-oriented systems Composite captures the essence of recursive composition in object-oriented terms
10
Formatting Goals & Constraints Encapsulating the Formatting Algorithm Compositor and Composition Design Patterns: Strategy Pattern
11
Formatting: Goals & Constraints
Representation and formatting are distinct: The ability to capture the document’s physical structure doesn’t tell us how to arrive at a particular structure. The editor must break text into lines, lines into columns, and so on, taking into account the user’s desires. Constraints : Flexibility Changeability The user configurations Formatting = breaking a collection of glyphs into lines, breaking lines into columns, and breaking columns into pages. The terms formatting and linebreaking are used interchangeably.
12
Formatting: Encapsulating the Formatting Algorithm
Formatting algorithms tend to be complex. The design of Lexi: Easy to change the formatting algorithms at least at the compile-time, if not at the run-time as well. Encapsulate the formatting algorithm in an object. This will isolate the algorithm and make it easily replaceable. More specifically: Define a separate class hierarchy for objects that encapsulate formatting algorithms The root of the hierarchy define an interface that supports a wide-range of formatting algorithms, and each subclass will implement an interface to carry out a particular algorithm Then, we can introduce a Glyph subclass that will structure its children automatically using a given algorithm object
13
Formatting: Compositor & Composition
Glyph Composition and Compositor Class Relationships Insert(Glyph, int i) children compositor Compositor Composition Insert(Glyph, g, int i) Compose() SetComposition() composition Glyph::Insert(g, i) compositor.Compose() ArrayCompositor TextCompositor SimpleCompositor Compose() Compose() Compose()
14
Formatting: Strategy Pattern
Encapsulating an algorithm in an object is the intent of Strategy Pattern Compositors are strategies; they encapsulate different formatting algorithms A composition is the context for a compositor strategy Strategy Pattern The key to applying the pattern to a particular problem is coming up with general strategy and context interfaces that support a broad range of algorithms.
15
Embellishing the UI Goals & Constraints Transparent Enclosure Monoglyph Design Patterns: Decorator Pattern
16
Embellishing the UI: Goals & Constraints
Two embellishments in Lexi’s user interface: The first adds a border around the text to demarcate the page of text The seconds adds scroll bars that let the user view different parts of the page Shouldn’t use inheritance to add embellishments to the user interface, why? To achieve flexibility to make it easy to add or remove these embellishments (especially at run-time) and without changing other classes
17
Embellishing the UI: Transparent Enclosure
Transparent enclosure combines the notion of: 1. Single-child (or single-component) composition and 2. Compatible interface Clients generally can’t tell whether they are dealing with the component and its enclosure, especially if the enclosure delegates all its operations to the component. But the enclosure can also augment the component’s behavior by doing work of its own before and after delegating an operation. The enclosure can also effectively add state to the component.
18
Embellishing the UI: Monoglyph
Draw(Window) MonoGlyph Class Relationships MonoGlyph component Draw(Window) Border Scroller Draw(Window) Draw(Window) DrawBorder(Window)
19
Embellishing the UI: Decorator Pattern
The Decorator pattern captures class and object relationships that support embellishment by transparent enclosure. In the Decorator pattern, the term embellishment refers to anything that adds state or behavior to an object.
20
Supporting Multiple Look-and-Feel Standards
Goals & Constraints Abstracting Object Creation Factories and Product Classes Design Patterns: Abstract Factory Pattern
21
Supporting Multiple Look-and-Feel Standards: Goals & Constraints
- The Lexi’s design goals are: To make it conform to multiple existing look-and-feel standards To make it easy to add support for new standards as they emerge - This is a portability issue The Lexi’s Design must support ultimate flexibility: Changing Lexi’s look and feel at run-time
22
Supporting Multiple Look-and-Feel: Abstracting Objects Creation
Assumptions: A set of abstract Glyph subclasses for each category of widget glyph A set of concrete subclasses for each abstract subclass that implement different look-and-feel standards Lexi must distinguish between widget glyphs for different look-and-feel styles This can be achieved by abstracting the process of object creation
23
Supporting Multiple Look-and-Feel: Factories & Product Classes
GUIFactory CreateScrollBar() CreateButton() GUIFactory Class Hierarchy MotiFactory PMFactory MacFactory CreateScrollBar() CreateButton() CreateScrollBar() CreateButton() CreateScrollBar() CreateButton() return new MotiButton return new PMButton return new MacButton return new MotiScrolBar return new PMScrolBar return new MacScrolBar
24
Supporting Multiple Look-and-Feel: Factories & Product Classes (cont’d)
Glyph Abstract Product Classes & Concrete Subclasses ScrollBar ScrollTo(int) Button Press() Menu Pupup() MotiScrollBar MacScrollBar PMScrollBar MotiButton MacButton PMButton
25
Supporting Multiple Look-and-Feel: Abstract Factory Pattern
Factories and products are the key players in the Abstract Factory pattern. This pattern captures how to create families of related product objects without instantiating classes directly The Abstract Factory pattern’s emphasis on families of products distinguishes it from other creational patterns, which involve only one kind of product object
26
Supporting Multiple Window Systems
Goals & Constraints Encapsulating Implementation Dependencies Window and WindowRep Design Patterns: Bridge Pattern
27
Supporting Multiple Window Systems: Goals & Constraints
This is another portability issue. Lexi must support multiple windows Lexi is designed to run on as many platforms as possibe for exactly the same reasons we support look-and-feel standards
28
Supporting Multiple Window Systems: Encapsulating Dependencies
glyph Window Glyph Redraw() Iconify() Lower() DrawLine() glyph->Draw(this) Draw(Window) ApplicationWindow IconWindow DialogWindow Iconify() Lower() owner->Lower()
29
Supporting Multiple Window Systems: Window & WindowRep
imp Raise() DrawRect(...) WindowImp DeviceRaise() DeviceRect(...) ApplicationWindow IconWindow DialogWindow MacWindowImp PMWindowImp XWindowImp DeviceRaise() DeviceRect(...) DeviceRaise() DeviceRect(...) DeviceRaise() DeviceRect(...)
30
Supporting Multiple Window Systems: Bridge Pattern
The relationship between Window and WindowRep is an example of the Bridge Pattern. The Bridge Pattern allows separate class hierarchies to work together even as they evolve independently. The Bridge Pattern allows for maintaining and enhancing the logical windowing abstractions without touching window system-dependent code, and vice versa.
31
User Operations Goals & Constraints Encapsulating the Request for a Service Commands and Histories Design Patterns: Command Pattern
32
User Operations: Goals and Constraints
Lexi provides different interfaces for the following operations: Creating a new document Opening, saving, and printing an existing document Cutting selected text out of the document and pasting it back in Changing the font and style of selected text Changing the formatting of text Quitting the application and plus many more... Lexi’s is also designed to support undo and redo of most but not all its functionality The challenge is to come up with a simple and extensible mechanism that satisfies all of these needs
33
User Operations: Encapsulating the Request of a Service
Command Execute() save PasteCommand FontCommand SaveCommand QuitCommand Execute() Execute() Execute() Execute() buffer newFont make selected text appear in newFont if (document is modified) { save->Execute() } quit the application paste buffer into document pop up a dialog box that lets the user name the document, and then save the document under that name Partial Command Class Hierarchy
34
User Operations: Commands & Histories
Glyph command MenuItem Command Clicked() Execute() command->Execute() MenuItem-Command Relationship
35
User Operations: Command Pattern
A command may delegate all, part, or none of the request’s implementation to other objects This is perfect for Lexi that must provide centralized access to functionality scattered throughout the application. Command Pattern The Command pattern objectifies the request for service. It decouples the creator of the request for a service from the executor of that service.
36
Spell Checking and Hyphenation
Goals & Constraints Encapsulating Traversal Traversal versus Traversal Actions Design Patterns: Iterator & Visitor Pattern
37
Spell Checking and Hyphenation: Goals and Constraints
The design problem involves textual analysis: Checking for misspelling Introducing hyphenation points where needed for good formatting. Constraints are similar to the formatting constraints Two pieces of the puzzle: Accessing the information to be analyzed Doing the analysis
38
Spell Checking and Hyphenation: Traversal vs. Traversal Actions
Command Execute() iterator PreorderIterator ArrayIterator ListIterator NullIterator First() Next() IsDone() CurrentItem() First() Next() IsDone() CurrentItem() First() Next() IsDone() CurrentItem() First() Next() IsDone() CurrentItem() currentItem root return true Glyph ... CreatorIterator() Iterator Class & Subclasses return new NullIterator
39
Spell Checking and Hyphenation: Iterator & Visitor Patterns
Iterator Pattern Iterator Pattern objectifies traversal algorithms over object structures. Visitor Pattern Visitor Pattern centralizes operations on object structures in one class so that these operations can be changed independently of the classes defining the structure.
40
Summary Eight different patterns applied in the Lexi’s design:
Composite to represent the document’s physical structure Strategy to allow different formatting algorithms Decorator for embellishing the user interface Abstract factory for supporting multiple look-and-feel standards Bridge to allow multiple windowing platforms Command for undoable user operations Iterator for accessing and traversaling object structures Visitor for allowing an open-ended number of analytical capabilities without complicating the document structure’s implementation
41
Discussion Questions 1. Define: Glyphs and Monoglyph
2. List the goals and constraints of: Formatting Support multiple look-and-feel standards User operations Embellishing the user interface 3. Explain how to achieve the goals for formatting
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.