Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

57
Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    223
  • download

    1

Transcript of Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Page 1: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Lecture 4:More UML Diagrams, Patterns

MISM/MSITFall 2001

Page 2: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Design Patterns A "hot topic" in O-O research Started by the book Design Patterns:

Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson and Vlissides (the Gang of Four).

The idea: some useful patterns of objects and associations recur in lots of places. So, find the "best" patterns, and encourage their use.

"Best'' usually means elegant, efficient, reusable, flexible.

Page 3: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Design Patterns The idea of formalizing recurring patterns has

origins in architecture; see A Pattern Language by Alexander, Ishikawa, Silverstein, Jacobson, Fiksdahl-King and Angel.

“Each design pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”

Page 4: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Elements of a Pattern Pattern name Problem Solution Consequences

Page 5: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example Pattern Name: Adaptor Intent: Convert the interface of a class into

another interface clients expect. Adaptor lets classes work together that couldn't otherwise because of incompatible interfaces.

Motivation: Sometimes a toolkit class that's designed for reuse isn't reusable only because its interface doesn't match the domain-specific interface an application requires.

Page 6: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example 1 Suppose we have a linked list class:

Now we need a stack. We can adapt the linked list class to a

stack by renaming the methods.

Page 7: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example 1 (cont.) This is the "class version'' of the

adaptor pattern:

Page 8: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example 1 (cont.)It's code looks like:  class linkedStack : private linkedList {public:

linkedStack() {length = 0;}void push(char c) {prepend(c); length++;}char pop() {length--; return del(); }int size() {return length;}bool isEmpty() {return (length == 0);}char top() {return first();}void reset() {release(); length = 0;}

private:int length;

};

Page 9: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example 2 A drawing editor letting users draw and

arrange graphical elements (lines, polygons, text, etc.) into pictures and diagrams.

There is a Shape class, and many subclasses. The LineShape and CircleShape and so forth

are easy, but a TextShape is quite difficult. There is a TextView class in the toolkit, but

its interface is quite different than that of Shape.

Solution: Define TextShape that adapts the TextView interface to the Shape interface.

Page 10: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Example 2 (cont.) Here is the “object version'' of this

pattern, for this example:

Page 11: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Consequences

The object adaptor Lets a single Adaptor work with many

Adaptees---that is, the Adaptee itself and all its subclasses (if any).

The Adaptor can also add functionality to all Adaptees at once.

Makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adaptor refer to the subclass rather than the Adaptee itself.

Page 12: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

A Larger Example: Designing a Document Editor A WYSIWYG editor called Lexi, similar in

intent to the old MacWrite. Design problems:

Document structure: what is the internal representation? This affects everything else!

Formatting: how does Lexi arrange text and graphics into lines and columns?

Embellishing the user interface: What if we want to add scroll bars, borders, etc.? These might change as the interface evolves.

Page 13: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Design Problems (cont.) Supporting multiple look-and-feel standards:

Motif, Presentation Manager, Mac, Windows… We want independence.

Supporting multiple window systems: MFC or TCL or Borland or…

User operations: Buttons, dialogs, pull-down menus, etc. Provide a uniform mechanism for accessing this scattered functionality, and undoing operations.

Spelling checking and hyphenation: How to support a variety of analytical operations, without having to make changes in lots of places?

Page 14: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Document Structure One perspective: a document is just a

collection of basic graphical elements. User perspective: the physical structure

of lines, columns, figures, tables, etc. The user wants to manipulate this

physical structure directly, through Lexi's interface, e.g., it should be possible to move an entire table, not just the individual lines and characters.

Page 15: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.
Page 16: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Internal Representation Choose an internal representation that

matches the document's physical structure.

It should support  maintaining the physical structure (the

arrangement of lines into columns, etc.) generating and presenting the document

visually mapping positions on the display to elements

in the internal representation.

Page 17: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Constraints Text and graphics should be treated

uniformly, so one set of operations works for both.

The internal representation shouldn't have to distinguish between a single element and a group of elements, so arbitrarily complex structures can be built.

It should be possible to distinguish types of elements; hyphenating a polygon makes no sense.

Page 18: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Recursive composition

Page 19: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Text and Graphics

Page 20: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Object Structure

Page 21: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Glyphs Glyphs have three basic

responsibilities. They know how to draw themselves, what space they occupy, and their children and parent.

This example shows the Composite pattern.

Page 22: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Glyph OperationsResponsibility Operations

appearance virtual void Draw(Window)virtual void Bounds(Rect)

hit detection virtual bool Intersects(const Point)

structure virtual void Insert(Glyph, int)virtual void Remove(Glyph)virtual Glyph Child(int)virtual Glyph Parent()

Page 23: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Formatting The Glyph arrangement gives a representation

of the document's physical structure. But how to determine that structure? Determining the structure is Lexi's job; the user

expects line breaking to happen for free. How will a formatting algorithm be applied to the

data structure? Formatting algorithms come in many flavors, but

they are mostly all complex. How to keep multiple algorithms encapsulated, and separate from the document structure?

Can we change the algorithm at run-time?

Page 24: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Strategy Pattern A solution is to provide a

Compositor class, having subclasses for the various formatting algorithms.

Then, a new Glyph subclass called Composition is added.

Page 25: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Composition/Compositor

Page 26: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Composition/Compositor A Composition object gets an instance

of a Compositor subclass when it's created, and it tells the compositor to Compose its glyphs when something changes (user adds new glyphs, reformats, etc.).

Responsibility Operations

what to format void SetComposition(Composition)

when to format virtual void Compose()

Page 27: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Unformatted Composition An unformatted Composition

contains only the visible glyphs (the document's basic content, no line breaks).

This probably should never be visible!

Page 28: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Composition/Compositor

Page 29: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Embellishing the User Interface Suppose we want to be able to add a

border, and scroll bars (and maybe more). 

One way: create subclasses of the Composition class. How many might we end up with? BorderedComposition, ScrollableComposition, BorderedScrollableComposition, etc.

Page 30: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Embellishments (cont.) Maybe object composition is a

better way. Suppose we make another class called Border.

But does Glyph contain Border, or does Border contain Glyph?

The latter requires no change in Glyph.

Page 31: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Embellishments (cont.) Borders have appearance, so they are a

kind of Glyph. Also, clients shouldn't care whether

glyphs have borders or not. When clients tell a plain, unbordered

glyph to draw itself, it should do so without embellishment.

If that glyph is in a border, the client shouldn't have to do anything differently.

Page 32: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Embellishments (cont.) So, make Border a subclass of Glyph. This is the idea of a transparent

enclosure. This combines single-child composition and compatible interfaces. Clients can't tell if they're dealing with the component or its enclosure.

Declare a subclass of Glyph called MonoGlyph as an abstract class for “embellishment glyphs.”

Page 33: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

The Decorator Pattern

Page 34: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Transparency

MonoGlyph stores a reference to a component and forwards all requests to it. So by default MonoGlyph is transparent to its user. 

void MonoGlyph::Draw(Window w) { _component.Draw(w);} At least one operation of the subclass extends the forwarded behavior: void Border::Draw(Window w) { MonoGlyph::Draw(w); DrawBorder(w);}

Page 35: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Multiple Embellishments To get just a border around a composition, create the composition, then ``wrap it'' in a Border, and then draw it: Window w = new Window;Composition comp = new Composition;Border bordComp = new Border(comp);bordComp.Draw(w); To make a bordered, scrollable composition, just repeat the pattern: Window w = new Window;Composition comp = new Composition;Border bordComp = new Border(comp);Scroller scrBordComp = new Scroller(bordComp);scrBordComp.Draw(w);

Page 36: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.
Page 37: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Supporting Multiple Look-and-Feel Standards Can Lexi be easily retargeted to a different

interface standard? Think Motif, X, Windows, Presentation Manager, and so on.

Suppose we have GIU libraries for each standard.

Suppose they all support the same “widgets,” that is, dialogs, buttons, scrollbars and so forth.

We don't want hard-coded instances likeScrollBar sb = new MotifScrollBar;

We might forget to change one, and end up with a Motif menu a Mac application!

Page 38: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Try This

scrollBar sb = new guiFactory.createScrollBar;

where guiFactory is an instance of a MotifFactory class. CreateScrollBar returns a new instance of the proper ScrollBar subclass for the look and feel desired.

Page 39: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Abstract Factory Pattern For clients, the effect is the same as

asking for a MotifScrollBar, but Motif isn't mentioned by name.

How to make this work? We'll use an abstract class GUIFactory,

that has methods like CreateScrollBar and CreateButton.

Subclasses implement these operations to return glyphs such as MotifScrollBar or PMScrollBar.

Page 40: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Abstract Factory Pattern

Page 41: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Getting That Look If it's clear at compile time what

the look and feel will be, then write GUIFactory guiFactory = new

MotifFactory;

Page 42: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Or Do It At StartupGUIFactory guiFactory;const char styleName = getenv("LOOK_AND_FEEL");

if (strcmp(styleName,"Motif") == 0) { guiFactory = new MotifFactory;} else if (strcmp(styleName, "Presentation_Manager") == 0) {

guiFactory = new PMFactory;}

Page 43: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

User Operations Some of Lexi's functionality is through the

WYSIWYG representation (enter/delete text, select ranges, etc.).

Other functionality is accessed through menus, buttons and keyboard accelerators. Things like create a new document open, save, print a document cutting and pasting changing fonts and styles changing formatting (alignment, justification) quitting

Page 44: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

User Operations (cont.) There may be multiple ways of accessing

these features, for instance from the menu, or by using an accelerator, or clicking a toolbar tool.

These operations are implemented in many different classes (so let's try to reduce dependencies). We also want undo and redo.

The solution is to encapsulate requests. A pull-down menu is just another kind of

glyph, but one that does something in response to a mouse-up event.

Page 45: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

The Solution Make MenuItem a subclass of Glyph, with the

ability to do some work in response to a request from a client (probably an event dispatcher).

One approach: make a subclass of MenuItem for each operation. But we don't make a glyph subclass for every letter, so this seems wrong.

Besides, we don't want to repeat the code in multiple places (for a menu item, a accelerator, a tool).

So, encapsulate the command, then attach it to the menu item.

Page 46: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Command Pattern

Page 47: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

MenuItem-Command Relationship

Buttons and other widgets can use commands in the same way.

Page 48: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Undoability Some commands should be reversible. The command for changing a font could

store the range of text and the old font.

Some commands should be reversible, but others not.

So add a Reversible() method to Command that returns a Boolean. 

Page 49: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Lexi can keep track of a command history, perhaps a doubly-linked list, like this:

past commands present

Each circle is a command object. Then undo and redo simply march along the command history.

Page 50: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Spell Check and Hyphenation Once again several algorithms are

available, with time/space/quality tradeoffs. There are other operations that we’d like to

apply to the whole document, or to part (searching, word counting, complexity analysis, etc.).

But the Glyph class shouldn’t have to change when a new capability is added.

Two problems: Accessing the information, and doing the analysis.

Page 51: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Accessing the Information In accessing information, different

Glyphs may store their children in different data structures.

Also, we may need to search in reverse order.

Currently, a Glyph uses an integer to locate its children.

We can improve this:

Page 52: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Accessing the Informationvoid First(Traversal kind)

void Next()

bool IsDone()

Glyph GetCurrent()

void Insert(Glyph)

  The type Traversal is an enumeration,

with values such as PREORDER and REVERSE.

Page 53: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Drawbacks This approach isn’t very good, because

it’s difficult to add new traversal strategies.

Putting this code in the Glyph classes would force us to constantly rewrite Glyph.

Once again, encapsulate the concept that varies, this time by introducing iterators.

Page 54: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Iterator Pattern

ArrayIterator

currentItem

First( )Next( )IsDone( )CurrentItem( )

Glyph

...( )CreateIterator( *

PreorderIterator

First( )Next( )IsDone( )CurrentItem( )

Iterator

First( )Next( )IsDone( )CurrentItem( )

*

*

root

iterators

*

Page 55: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Iterators We can add new types of traversals

without modifying the glyph classes. Iterators store their own copy of the

state of traversal, we can have multiple traversals going simultaneously.

We could also parameterize iterators, so they would apply to other classes as well.

Page 56: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Traversals vs. Traversal Actions Where should the responsibility for

actions be? In the iterator itself? No! Different analyses require the same type

of iterator. We could put specific functions likeCheckMe(SpellingChecker checker)

in each glyph, but “that would be wrong.”

Better to use the Visitor pattern.

Page 57: Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.

Visitor Pattern

SpellCheckVisitor HyphenationVisitor

Glyph

... ()Accept(Visitor)

Visitor

VisitCharacter (Character)VisitRow (Row)VisitImage (Image)