STAT 598W Lecture 18 Design Patterns. A "hot topic" in O-O research Started by the book Design Patterns: Elements of Reusable Object-Oriented Software.

Slides:



Advertisements
Similar presentations
Understand and appreciate Object Oriented Programming (OOP) Objects are self-contained modules or subroutines that contain data as well as the functions.
Advertisements

GoF Sections 2.7 – 2.9 More Fun with Lexi. Lexi Document Editor Lexi tasks discussed:  Document structure  Formatting  Embellishing the user interface.
OOP Design Patterns Chapters Design Patterns The main idea behind design patterns is to extract the high level interactions between objects and.
The Bridge Pattern.. Intent Decouple an abstraction from its implementation so that the two can vary independently Also known as: Handle/Body.
Plab – Tirgul 12 Design Patterns
Iterators T.J. Niglio Computer & Systems Engineering Fall 2003 Software Design & Documentation Object Behavioral.
GoF: Document Editor Example
Design Patterns CS is not simply about programming
GoF: Document Editor Example A Case Study.
Design Patterns. CS351 - Software Engineering (AY2007)Slide 2 Behavioral patterns Suppose we have an aggregate data structure and we wish to access the.
Software Design and Documentation Individual Presentation: Composite Pattern 9/11/03.
Design Patterns Based on Design Patterns. Elements of Reusable Object-Oriented Software. by E.Gamma, R. Helm, R. Johnson,J. Vlissides.
The Composite Pattern.. Composite Pattern Intent –Compose objects into tree structures to represent part-whole hierarchies. –Composite lets clients treat.
Lecture 4: More UML Diagrams, Patterns MISM Summer 2001.
GoF Sections 2.7 – 2.9 More Fun with Lexi. Lexi Document Editor Lexi tasks discussed:  Document structure  Formatting  Embellishing the user interface.
Prototype Creational Design Pattern By Brian Cavanaugh September 22, 2003 Software, Design and Documentation.
Copyright © Active Frameworks Inc. - All Rights Reserved - V2.0Document Editor - Page L2-5 PS95&96-MEF-L9-5 Dr. M.E. Fayad  Document Structure.
Lecture 4: More UML Diagrams, Patterns MISM/MSIT Fall 2001.
ECE450 - Software Engineering II1 ECE450 – Software Engineering II Today: Design Patterns VI Composite, Iterator, and Visitor Patterns.
© 2008 Hewlett-Packard Development Company, L.P. The information contained herein is subject to change without notice Design Patterns Case Study: Designing.
1 An introduction to design patterns Based on material produced by John Vlissides and Douglas C. Schmidt.
OBJECT ORIENTED PROGRAMMING IN C++ LECTURE
ADVANCED MICROSOFT POWERPOINT Lesson 6 – Creating Tables and Charts
1 PH Chapter 1 (pp. 1-10) GoF Composite Pattern (pp ) PH Ch 2 through Fundamentals (pp ) Presentation by Julie Betlach 5/28/2009.
Programming With Java ICS201 University Of Hail1 Chapter 12 UML and Patterns.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Design Patterns.
1 Dept. of Computer Science & Engineering, York University, Toronto CSE3311 Software Design Adapter Pattern Façade pattern.
Prof. Aiken CS 169 Lecture 51 Design Patterns CS169 Lecture 5.
Design a Document Editor Oksana Protsyk Yaroslav Kaplunskiy.
CSE 332: Design Patterns (Part I) Introduction to Design Patterns Design patterns were mentioned several times so far –And the Singleton Pattern was discussed.
A Case Study: Designing a Document Editor “ Lexi ”
An Introduction to Design Patterns. Introduction Promote reuse. Use the experiences of software developers. A shared library/lingo used by developers.
ISP666 MVC & Design Patterns. Outline Review Event Programming Model Model-View-Controller Revisit Simple Calculator Break Design Patterns Exercise.
SOEN 6011 Software Engineering Processes Section SS Fall 2007 Dr Greg Butler
Copyright © 2002, Systems and Computer Engineering, Carleton University Patterns.ppt * Object-Oriented Software Development Part 11.
Creational Patterns CSE301 University of Sunderland Harry R Erwin, PhD.
CSCI-383 Object-Oriented Programming & Design Lecture 13.
Pattern Hatching - John Vlissides Pages 85 – 101 Todd Anderson
Design Patterns CSCI 5801: Software Engineering. Design Patterns.
Lexi case study (Part 2) Presentation by Matt Deckard.
18 April 2005CSci 210 Spring Design Patterns 1 CSci 210.
L11-12: Design Patterns Definition Iterator (L4: Inheritance)‏ Factory (L4: Inheritance)‏ Strategy (L5: Multiple Inheritance)‏ Composite (L6: Implementation.
Software Design Patterns (1) Introduction. patterns do … & do not … Patterns do... provide common vocabulary provide “shorthand” for effectively communicating.
GoF: Document Editor Example Rebecca Miller-Webster.
CSE 403 Lecture 14 Design Patterns. Today’s educational objective Understand the basics of design patterns Be able to distinguish them from design approaches.
Design Patterns CS 124 Reference: Gamma et al (“Gang-of-4”), Design Patterns.
Structural Design Patterns
Design Patterns CSIS 3701: Advanced Object Oriented Programming.
ECE450 - Software Engineering II1 ECE450 – Software Engineering II Today: Design Patterns VIII Chain of Responsibility, Strategy, State.
CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can.
08 - StructuralCSC4071 Structural Patterns concerned with how classes and objects are composed to form larger structures –Adapter interface converter Bridge.
Sadegh Aliakbary. Copyright ©2014 JAVACUP.IRJAVACUP.IR All rights reserved. Redistribution of JAVACUP contents is not prohibited if JAVACUP.
Software Design Patterns Curtsy: Fahad Hassan (TxLabs)
COMPOSITE PATTERN NOTES. The Composite pattern l Intent Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients.
CLASSIFICATION OF DESIGN PATTERNS Hladchuk Maksym.
Design Patterns CSCE 315 – Programming Studio Spring 2013.
Examples (D. Schmidt et al)
Design Patterns: MORE Examples
MPCS – Advanced java Programming
Design Patterns Lecture part 2.
Introduction to Design Patterns
Case Study 1: Designing a Document Editor
Behavioral Design Patterns
Chapter-II A Case Study:
Advanced Programming Behnam Hatami Fall 2017.
Software Engineering Lecture 7 - Design Patterns
Design Patterns A Case Study: Designing a Document Editor
A Case Study: Designing a Document Editor
Introduction to Design Patterns
Presentation transcript:

STAT 598W Lecture 18 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.

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.”

Reasons to use It is much easier to explain the code to someone else We obtain an immediate toolbox for solving any problem put in front of us: when confronted with a programming problem, we can think along the way “what design pattern is appropriate here?” Even none of the known patterns are appropriate, examinations of the problem through the lens of design patterns will help us have a better understanding of the problem

Design pattern: common ones The design patterns can be generally categorized into three types: Creational patterns Structural patterns Behavioral patterns

Design patterns: Creational Virtual copy constructor The use of “clone” in polymorphism The factory: To allow us to have an object that spits out objects when we need them (create objects of the relevant type) Singleton: One way to implement the factory. The feature is that there is a single copy of the object which is accessible from everywhere, without introducing global variables and all the difficulties they imply

Design pattern: Structural Adapter: The adapter is a class that translates an interface into a form that other classes expect. It is most useful when we wish to fit code into a structure for which it was not originally designed, either because we have changed our way of doing things or because the code originates elsewhere Bridge: The bridge defines an interface, and acts as an intermediary between a client class and the classes implementing the interface Decorator: The decorator allows to change the behavior of a class at run-time without changing its interface. We can decorate as many time as we like because decoration does not change the interface

Design patterns: Behavioral Strategy: We defer an important part of algorithm to an inputted object. This allows us to easily change how this particular part behaves Template: Rather than inputting an aspect of the algorithm, we defer part of the algorithm’s implementation to an inherited class. The base class only provides the structure of how the different parts of the algorithm fits together, it does not specify all the implementations Iterator: Iterator is one of the most important component of the standard library. The algorithms in STL are performed over iterators.

Elements of a Pattern Pattern name Problem Solution Consequences

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.

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.

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

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; };

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.

Example 2 (cont.) Here is the “object version'' of this pattern, for this example:

Consequences The object adaptor Lets a single Adaptor work with many Adaptees---that is, the Adaptee itself and all its subclasses (if any). Makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adaptor refer to the subclass rather than the Adaptee itself.

Example 2: Pricing Exotic Options with MC Implement the pricing of path- dependent exotic options (by using Monte-Carlo simulation). Summarize the statistics obtained from the pricing procedure To be specific, price the Asian Options Use design patterns to solve this programming problem

Example 2: Identify components There are four distinct actions we need to price the path-dependent exotic options: The generation of the stock price path The generation of the cash-flows given a stock price path The discounting and summing of cash-flows for a given path The averaging of the prices over all the paths a summarization of the statistics

Example 2: Encapsulation We must encapsulate these actions into different objects (classes), and this is one of the most important step in OOP design For 1, we need to design a “path generator” class For 2, since it is about the type of the path- dependent option, we should design a “PathDependent” class For 1, 2, and 3, they should be all encapsulated in a class that price the exotic options. Name this class “ExoticEngine” For 4, we need to design a “statistics collector” class to do the average and record the statistics

Example 2: Communications Path generator gets the times of the spot prices required form the PathDependent product and then generate a vector of spot values The ExoticEngine gets information about the possible cash-flow times from the PahtDependent product, it will use this information to compute the discounted factors and reserve a vector to store the cash- flows The ExoticEngine gets the vector of spot values from the Path generator The Exotic Engine passes the vector of spot values to the PathDependent product, which passes back the number of cash-flows, and puts their values into the vector previously reserved The ExoticEngine discounts the cash-flows and sums them up, it then passes the total value to the Statistic collector The Statistics collector returns the final price and the summary of statistics

Example 2: Design patterns There are multiple Design Patterns that we can use The implementation of Statistics collector can be realized by using the “Strategy Pattern” The PathDependent class and ExoticEngine class can be implemented by using the “Template Pattern”, because these two classes are the base classes which only define the interfaces. The detailed implementation should be defined later in derived classes We can use the “Bridge Pattern” to deal with the deep copying actions We can use the “Adapter Pattern” to generate a random path from some random number generators We can use the “Decorator Pattern” to realize some complicated implementations based on simple ones and maintain the same interfaces (e.g. Statistical collector)

Example 2: Base classes “RandomBase” class: the path generator “PathDependent” class: the path-dependent option type “ExoticEngine” class: the exotic option pricing engine “StatisticsMC” class: the statistics collector class As can be seen, the base classes are all abstract, they only define the interfaces we expect the object to have. The implementations will be defined later in derived classes. Through this,we can maximize the usage of our codes and make things easy to understand, revise, and maintain

Example 2: Derived class “AntiThetic” class: the path generator with variance reduction “PathDependentAsian” class: the Asian option “ExoticBSEngine” class: the exotic option pricing engine in the Black-Schole world “ConvergenceTable” class: the statistic collector that can returns the convergence rate of the pricing procedure The detailed implementations are defined in derived classes

A Larger Example: Designing a Document Editor (Read by yourself after class) 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.

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?

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.

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.

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.

Recursive composition

Text and Graphics

Object Structure

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.

Glyph Operations Responsibility 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()

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?

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.

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.). ResponsibilityOperations what to format void SetComposition(Composition) when to format virtual void Compose()

Unformatted Composition An unformatted Composition contains only the visible glyphs (the document's basic content, no line breaks). This probably should never be visible!

Composition/Compositor

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.

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.

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.

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.''

The Decorator Pattern

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); }

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);

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 like ScrollBar sb = new MotifScrollBar; We might forget to change one, and end up with a Motif menu a Mac application!

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.

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.

Abstract Factory Pattern

Getting That Look If it's clear at compile time what the look and feel will be, then write GUIFactory * guiFactory = new MotifFactory;

Or Do It At Startup GUIFactory * 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; }

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

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.

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.

Command Pattern

MenuItem-Command Relationship Buttons and other widgets can use commands in the same way.

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.

Undoability 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.

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.

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:

Accessing the Information void 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.

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.

Iterator Pattern

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.

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 like CheckMe(SpellingChecker checker) in each glyph, but “that would be wrong.” Better to use the Visitor pattern.

Visitor Pattern