object oriented patterns frameworks
play

Object-Oriented Patterns & Frameworks Dr. Douglas C. Schmidt - PowerPoint PPT Presentation

Object-Oriented Patterns & Frameworks Dr. Douglas C. Schmidt d.schmidt@vanderbilt.edu www.dre.vanderbilt.edu/ ~schmidt Professor of E E CS Vanderbilt University Nashville, Tennessee Pattern & Framework Tutorial Douglas C. Schmidt


  1. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Frameworks • Frameworks exhibit • Frameworks provide • Frameworks are “inversion of control” at integrated domain-specific “semi-complete” runtime via callbacks structures & functionality applications Application-specific functionality Scientific Mission Visualization Computing E-commerce GUI Networking Database 21

  2. Pattern & Framework Tutorial Douglas C. Schmidt Motivation for Frameworks Air Air GPS AP HUD Frame Nav Nav Nav Nav HUD HUD HUD Frame Air AP AP AP FLI R FLI R FLI R FLI R Frame Air I FF GPS GPS I FF GPS I FF I FF Frame Cyclic Cyclic Cyclic Cyclic Exec Exec Exec Exec UCAV F/ A-18 A/ V-8B F-15 Legacy embedded systems have Consequence: Small historically been: HW/SW changes have • Stovepiped big (negative) impact • Proprietary on system QoS & • Brittle & non-adaptive maintenance • Expensive • Vulnerable 22

  3. Pattern & Framework Tutorial Douglas C. Schmidt Motivation for Frameworks F/ A 18 A/ V 8-B product product UCAV variant variant product F-15 Air variant product FLI R Frame AP variant HUD GPS Nav I FF Domain-specific Services Common Middleware Services Distribution Middleware Host I nfrastructure Middleware Product-line OS & Network Protocols architecture Hardware (CPU, Memory, I / O) • Fra ram ew ork rks factors out many reusable general-purpose & domain-specific services from traditional DRE application responsibility • Essential for pr produ duct -line arch chit ect ct ures ( PLAs) • Product-lines & frameworks offer many configuration opportunities • e.g., component distribution/deployment, OS, protocols, algorithms, etc. 23

  4. Pattern & Framework Tutorial Douglas C. Schmidt Categories of OO Frameworks • White-box frameworks are reused by subclassing, which usually requires understanding the implementation of the framework to some degree • Black-box framework is reused by parameterizing & assembling framework objects, thereby hiding their implementation from users • Each category of OO framework uses different sets of patterns, e.g.: – Black-box frameworks reply heavily on object composition patterns, such – White-box frameworks rely heavily as Strategy & Decorator on inheritance-based patterns, such as Template Method & State 24 Many frameworks fall in between white-box & black-box categories

  5. Pattern & Framework Tutorial Douglas C. Schmidt Commonality & Variability Analysis in Frameworks • Framework characteristics • Applying SCV to avionics mission computing are captured via Scope, • Scope defines the domain & context of Commonalities, & the framework Variabilities (SCV) analysis • Component architecture, object- • This process can be oriented application frameworks, & applied to identify associated components, e.g., GPS, commonalities & Airframe, & Display variabilities in a domain Reusable Application to guide development of Components a framework Air FLI R Frame AP HUD GPS Nav Reusable Architecture I FF Framework Domain-specific Services Common Middleware Services Distribution Middleware Host I nfrastructure Middleware OS & Network Protocols 25

  6. Pattern & Framework Tutorial Douglas C. Schmidt Applying SCV to an Avionics Framework • Com m onalit ies describe the attributes that are common across all members of the framework • Common object-oriented frameworks & set of component types • e.g., GPS, Airframe, Navigation, & Display components • Common middleware infrastructure GPS Navigation Airframe Heads Up • e.g., Real-time Component Component Component Display CORBA & a variant of Lightweight CORBA Component Common Components Model (CCM) called Domain-specific Services Prism Common Middleware Services Distribution Middleware Host I nfrastructure Middleware OS & Network Protocols Hardware (CPU, Memory, I / O) 26

  7. Pattern & Framework Tutorial Douglas C. Schmidt Applying SCV to an Avionics Framework • Vari riabilit ies describe the GPS Display Airframe Heads Up attributes unique to the Component Component Component Display different members of the framework Common Components • Product-dependent component GPS = 40 Hz GPS=20Hz GPS = 20 Hz Air Air Fram Air GPS implementations (GPS/INS) Fram Nav Frame Nav Nav HUD HUD Nav e AP e HUD AP AP FLIR FLIR AP FLIR FLIR • Product-dependent IF IF GPS GPS IFF IFF HUD F GPS F component connections F/A 18 F F 15K UCAV • Product-dependent component assemblies (e.g., different weapons systems for different customers/countries) Domain-specific Services Common Middleware Services • Different hardware, OS, & Distribution Middleware network/bus configurations Host I nfrastructure Middleware OS & Network Protocols Hardware (CPU, Memory, I / O) 27

  8. Pattern & Framework Tutorial Douglas C. Schmidt Comparing Reuse Techniques LOCAL Class Library (& STL) Architecture APPLICATION- INVOCATIONS Math SPECIFIC IPC FUNCTIONALITY ADTs • A class is an implementation unit in an OO Files programming language, i.e., a reusable t ype e Strings GUI that often implements pat t e t t erns GLUE EVENT Locks CODE LOOP • Classes in class libraries are typically passive NETWORKI NG Framework Architecture Reactor ADTs • A fra ram ew ork rk is an integrated set of Strings APPLI CATI ON- classes that collaborate to form a reusable SPECI FI C I NVOKES CALL GUI FUNCTI ONALI TY BACKS architecture for a family of applications Files Locks • Frameworks implement pat t e t t ern DATABASE langu guage ges Component & Service-Oriented Architecture Naming Events • A com om pon onent is an encapsulation unit with one or more interfaces that provide clients with access to its services Logging Locking • Components can be deployed & configured 28 Middleware Bus via assem ssem blies es

  9. Pattern & Framework Tutorial Douglas C. Schmidt Taxonomy of Reuse Techniques Class Frameworks Components Libraries Micro-level Meso-level Macro-level “Semi- Stand-alone Stand-alone complete” composition entities language entities applications Domain- Domain-specific Domain-specific or independent Domain-independent Borrow caller’s Inversion of Borrow caller’s thread control thread 29

  10. Pattern & Framework Tutorial Douglas C. Schmidt Benefits of Frameworks • Design reuse AdminClient PickingClient • e.g., by guiding application Admin Admin Picking Picking Controllers Views Controllers Views developers through the steps Thin UI Clients necessary to ensure successful Proxy Proxy creation & deployment of software Broker Broker OS-Access Component Layer Repository Distribution Communication Component Infrastructure Services Configurator Broker Broker Scheduler/ Reactor ActivationList Service Request Logging ThreadPool Handler * Service Service Request Request Concurrency Infrastructure WarehouseRepHalfX 30

  11. Pattern & Framework Tutorial Douglas C. Schmidt Benefits of Frameworks • Design reuse package org.apache.tomcat.session; import org.apache.tomcat.core.*; import org.apache.tomcat.util.StringManager; import java.io.*; • e.g., by guiding application import java.net.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; developers through the steps /** * Core implementation of a server session * necessary to ensure successful * @author James Duncan Davidson [duncan@eng.sun.com] * @author James Todd [gonzo@eng.sun.com] */ creation & deployment of software public class ServerSession { private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); • I mplementation reuse private Hashtable values = new Hashtable(); private Hashtable appSessions = new Hashtable(); private String id; private long creationTime = System.currentTimeMillis();; private long thisAccessTime = creationTime; • e.g., by amortizing software private int inactiveInterval = -1; ServerSession(String id) { this.id = id; lifecycle costs & leveraging } public String getId() { return id; previous development & } public long getCreationTime() { return creationTime; optimization efforts } public ApplicationSession getApplicationSession(Context context, boolean create) { ApplicationSession appSession = (ApplicationSession)appSessions.get(context); if (appSession == null && create) { // XXX // sync to ensure valid? appSession = new ApplicationSession(id, this, context); appSessions.put(context, appSession); } // XXX // make sure that we haven't gone over the end of our // inactive interval -- if so, invalidate & create // a new appSession return appSession; } void removeApplicationSession(Context context) { appSessions.remove(context); } 31

  12. Pattern & Framework Tutorial Douglas C. Schmidt Benefits of Frameworks • Design reuse • e.g., by guiding application developers through the steps necessary to ensure successful creation & deployment of software • I mplementation reuse • e.g., by amortizing software lifecycle costs & leveraging previous development & optimization efforts • Validation reuse • e.g., by amortizing the efforts of validating application- & platform- independent portions of software, thereby enhancing software reliability & scalability 32

  13. Pattern & Framework Tutorial Douglas C. Schmidt Limitations of Frameworks • Frameworks are powerful, but can be hard to use effectively (& even harder to create) for many application developers • Commonality & variability analysis requires significant domain knowledge & OO design/implementation expertise • Significant time required to evaluate applicability & quality of a framework for a particular domain • Debugging is tricky due to inversion of control • V&V is tricky due to “late binding” • May incur performance degradations due to extra (unnecessary) levels of indirection www.cs.wustl.edu/ ~schmidt/PDF/Queue-04.pdf Many frameworks limitations can be addressed with knowledge of patterns! 33

  14. Pattern & Framework Tutorial Douglas C. Schmidt Using Frameworks Effectively Observations • Since frameworks are powerful—but but hard to develop & use effectively by application developers—it’s often better to use & customize COTS frameworks than to develop in-house frameworks • Classes/components/services are easier for application developers to use, but aren’t as powerful or flexible as frameworks Successful projects are therefore often organized using the “funnel” model 34

  15. Pattern & Framework Tutorial Douglas C. Schmidt Stages of Pattern & Framework Awareness 35

  16. Pattern & Framework Tutorial Douglas C. Schmidt Part II: Case Study: Expression Tree Application Goals • Develop an object-oriented expression tree evaluator program using patterns & frameworks • Demonstrate commonality/variability analysis in the context of a concrete application example Binary • Illustrate how OO frameworks can be Nodes combined with the generic programming features of C+ + & STL • Compare/contrast OO & non-OO approaches Unary Node Leaf Nodes 36

  17. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Expression Tree Application • Expression trees consist of nodes containing operators & operands • Operators have different precedence levels, different associativities, & different arities, e.g.: • Multiplication takes precedence over addition • The multiplication operator has two Binary Nodes arguments, whereas unary minus operator has only one • Operands can be integers, doubles, variables, etc. Unary • We'll just handle integers in this Node application • Application can be extended easily Leaf Nodes 37

  18. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Expression Tree Application • Trees may be “evaluated” via different traversal orders • e.g., in-order, post-order, pre-order, level-order • The evaluation step may perform various operations, e.g.: • Print the contents of the expression tree Binary • Return the “value" of the expression tree Nodes • Generate code • Perform semantic analysis & optimization Unary • etc. Node Leaf Nodes 38 See tree-traversal example

  19. Pattern & Framework Tutorial Douglas C. Schmidt Using the Expression Tree Application • By default, the expression tree application can run in “succinct mode,” e.g.: % tree-traversal > 1+ 4* 3/2 7 % tree-traversal -v > (8/4) * 3 + 1 format [in-order] 7 expr [expression] ^ D print [in-order|pre-order|post-order|level-order] eval [post-order] • You can also run quit the expression > format in-order tree application > expr 1+ 4* 3/2 in “verbose > eval post-order mode,” e.g.: 7 > quit 39

  20. Pattern & Framework Tutorial Douglas C. Schmidt How Not to Design an Expression Tree Application A typical algorithmic-based solution for implementing expression trees uses a C struct/union to represent the main data structure typedef struct Tree_Node { enum { NUM, UNARY, BINARY } tag_; short use_; /* reference count */ union { char op_[2]; int num_; } o; #define num_ o.num_ #define op_ o.op_ union { struct Tree_Node *unary_; struct { struct Tree_Node *l_, *r_;} binary_; } c; #define unary_ c.unary_ #define binary_ c.binary_ } Tree_Node; 40

  21. Pattern & Framework Tutorial Douglas C. Schmidt How Not to Design an Expression Tree Application Here’s the memory layout & class diagram for a struct Tree_Node : 41

  22. Pattern & Framework Tutorial Douglas C. Schmidt How Not to Design an Expression Tree Application A typical algorithmic implementation uses a switch statement & a recursive function to build & evaluate a tree, e.g.: void print_tree (Tree_Node *root) { switch (root->tag_) case NUM: printf (“%d”, root->num_); break; case UNARY: printf ("(%s”, root->op_[0]); print_tree (root->unary_); printf (")"); break; case BINARY: printf ("("); print_tree (root->binary_.l_); // Recursive call printf (“%s”, root->op_[0]); print_tree (root->binary_.r_); // Recursive call printf (")"); break; default: printf ("error, unknown type "); } 42

  23. Pattern & Framework Tutorial Douglas C. Schmidt Limitations with the Algorithmic Approach • Little or no use of encapsulation: • Data structures are “passive” implementation details available to functions that do their work clients explicitly • Incomplete modeling of the • The program organization makes it application domain, which results in hard to extend • Tight coupling between • e.g., Any small changes will nodes/edges in union ripple through entire representation design/implementation • Complexity being in algorithms • Easy to make mistakes switching rather than the data structures, on type tags e.g., switch statements are used to • Wastes space by making worst- select between various types of case assumptions wrt structs & nodes in the expression trees unions 43

  24. Pattern & Framework Tutorial Douglas C. Schmidt An OO Alternative Using Patterns & Frameworks • Start with OO modeling of the “expression tree” application domain Binary Nodes • Model a tree as a collection of nodes • Nodes are represented in an inheritance hierarchy that captures the particular properties Unary Node of each node • e.g., precedence levels, different associativities, & different arities Leaf Nodes • Conduct commonality/variability analysis (CVA) to determine stable interfaces & points of variability • Apply patterns to guide design/implementation of framework • Integrate with C+ + STL algorithms/containers where appropriate 44

  25. Pattern & Framework Tutorial Douglas C. Schmidt Design Problems & Pattern-Oriented Solutions Design Problem Pattern(s) Binary Expression tree structure Composite Nodes Encapsulating variability & Bridge simplifying memory management Unary Tree printing & evaluation Iterator & Visitor Node Consolidating user Command operations Leaf Ensuring correct protocol State Nodes for commands Consolidating creation of Abstract Factory Variabilities & Factory Method Parsing expressions & Interpreter & creating expression tree Builder 45

  26. Pattern & Framework Tutorial Douglas C. Schmidt Design Problems & Pattern-Oriented Solutions Design Problem Pattern(s) Binary Driving the application Reactor Nodes event flow Supporting multiple Template Method operation modes & Strategy Unary Centralizing global Singleton Node objects effectively Implementing STL Prototype Leaf iterator semantics Nodes Eliminating loops via the Adapter STL std::for_each() algorithm Provide no-op commands Null Object None of these patterns are restricted to expression tree applications… 46

  27. Pattern & Framework Tutorial Douglas C. Schmidt Managing Global Objects Effectively Goals: Verbose mode % tree-traversal -v – Centralize access to format [in-order] objects that should be expr [expression] visible globally, e.g.: print [in-order|pre-order|post-order|level-order] – command-line options eval [post-order] that parameterize the quit behavior of the program > format in-order – The object (Reactor) > expr 1+ 4* 3/2 that drives the main > eval post-order event loop 7 Constraints/ forces: > quit – Only need one instance Succinct mode of the command-line % tree-traversal options & Reactor > 1+ 4* 3/2 – Global variables are 7 problematic in C+ + 47

  28. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Centralize Access to Global Instances Rather than using global variables, create a central access point to global instances, e.g.: int main (int argc, char *argv[]) { // Parse the command-line options. if (!Options::instance ()->parse_args (argc, argv)) return 0; // Dynamically allocate the appropriate event handler // based on the command-line options. Expression_Tree_Event_Handler *tree_event_handler = Expression_Tree_Event_Handler::make_handler (Options::instance ()->verbose ()); // Register event handler with the reactor. Reactor::instance ()->register_input_handler (tree_event_handler); // ... 48

  29. Pattern & Framework Tutorial Douglas C. Schmidt Singleton object creational I ntent ensure a class only ever has one instance & provide a global point of access Applicability – when there must be exactly one instance of a class, & it must be accessible from a well-known access point – when the sole instance should be extensible by subclassing, & clients should be able to use an extended instance without modifying their code Structure If (uniqueInstance == 0) uniqueInstance = new Singleton; return uniqueInstance; 49

  30. Pattern & Framework Tutorial Douglas C. Schmidt Singleton object creational Consequences Known Uses + reduces namespace pollution – Unidraw's Unidraw object + makes it easy to change your mind & – Smalltalk-80 ChangeSet, allow more than one instance the set of changes to code + allow extension by subclassing – InterViews Session object – same drawbacks of a global if misused See Also – implementation may be less efficient – Double-Checked Locking than a global Optimization pattern from – concurrency pitfalls strategy creation & POSA2 communication overhead – “To Kill a Singleton” I mplementation www.research.ibm.com/ designpatterns/pubs/ – static instance operation ph-jun96.txt – registering the singleton instance – deleting singletons 50

  31. Pattern & Framework Tutorial Douglas C. Schmidt Expression Tree Structure Goals: – Support “physical” structure of expression tree • e.g., binary/unary operators & operators – Provide “hook” for enabling arbitrary operations on tree nodes • Via Visitor pattern Constraints/ forces: – Treat operators & operands uniformly – No distinction between one & many Unary Node Leaf Nodes 51

  32. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Recursive Structure • Model a tree as a recursive Binary collection of nodes Nodes • Nodes are represented in an inheritance hierarchy that captures the particular properties of each node Unary • e.g., precedence levels, different Node associativities, & different arities • Binary nodes recursively contain Leaf two other nodes; unary nodes Nodes recursively contain one other node 52

  33. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Tree Structure & Creation Patterns Interpreter < < use > > Expression_Tree_ Expression_Tree Interpreter_Context Context Interpreter < < create > > Component_Node Symbol Composite_ Composite_ Leaf_Node Number Operator Unary_Operator Binary_Node Unary_Node < < create > > Composite_ Composite_ Composite_ Add Substract Negate Add_Node Substract_Node Negate_Node Composite_ Composite_ Multiply Divide < < create > > Multiply_Node Divide_Node Composite Builder 53

  34. Pattern & Framework Tutorial Douglas C. Schmidt Component_Node Abstract base class for composable expression tree node objects I nterface : virtual ~ Component_Node (void)= 0 virtual int item (void) const virtual Component_Node * left (void) const virtual Component_Node * right (void) const virtual void accept (Visitor &visitor) const Subclasses : Leaf_Node , Composite_Unary_Node , Composite_Binary_Node , etc. Commonality : base class interface is used by all nodes in an expression tree Variability : each subclass defines state & method implementations that are specific for the various types of nodes 54

  35. Pattern & Framework Tutorial Douglas C. Schmidt Component_Node Hierarchy Note the inherent recursion in this hierarchy  i.e., a Composite_Binary_Node is a Component_Node & a Composite_Binary_Node also has Component_Node s! 55

  36. Pattern & Framework Tutorial Douglas C. Schmidt Composite object structural I ntent treat individual objects & multiple, recursively-composed objects uniformly Applicability objects must be composed recursively, and no distinction between individual & composed elements, and objects in structure can be treated uniformly Structure e.g., Component_Node e.g., Composite_Unary_Node, Composite_Binary_Node, etc. e.g., Leaf_Node 56

  37. Pattern & Framework Tutorial Douglas C. Schmidt Composite object structural Consequences Known Uses + uniformity: treat components the same – ET+ + Vobjects regardless of complexity – InterViews Glyphs, + extensibility: new Component subclasses work Styles wherever old ones do – Unidraw Components, – overhead: might need prohibitive numbers of MacroCommands objects – Directory structures – Awkward designs: may need to treat leaves as on UNIX & Windows lobotomized composites – Naming Contexts in I mplementation CORBA – do Components know their parents? – MIME types in SOAP – uniform interface for both leaves & composites? – don’t allocate storage for children in Component base class – responsibility for deleting children 57

  38. Pattern & Framework Tutorial Douglas C. Schmidt Parsing Expressions & Creating Expression Tree Goals: Constraints/ forces: – Simplify & centralize the creation of all – Don’t recode existing nodes in the composite expression tree clients – Extensible for future types of – Add new expressions expression orderings without recompiling “in-order” expression = -5* (3+ 4) “pre-order” expression = * -5+ 34 “post-order” expression = 5-34+ * “level-order” expression = * -+ 534 Unary Node Leaf Nodes 58

  39. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Build Parse Tree Using Interpreter • Each make_tree() method in the appropriate state object uses an interpreter to create a parse tree that corresponds to the expression input • This parse tree is then traversed to build each node in the corresponding expression tree Interpreter_Context In_Order_ Uninitialized_ State make_tree() Interpreter 59

  40. Pattern & Framework Tutorial Douglas C. Schmidt Interpreter Parses expressions into parse tree & generate corresponding expression tree I nterface: Interpreter (void) virtual ~ Interpreter (void) Expression interpret (Interpreter_Context &context, uses _Tree const std::string &input) Interpreter_Context (void) creates ~ Interpreter_Context (void) Symbol (Symbol * left, int get (std::string variable) Symbol * right) void set (std::string variable, int value) virtual ~ Symbol (void) void print (void) virtual int precedence (void)= 0 void reset (void) virtual Component_Node * build (void)= 0 Commonality : Provides a common interface for parsing expression input & building expression trees Variability : The structure of the expression trees can vary depending on the format & contents of the expression input 60

  41. Pattern & Framework Tutorial Douglas C. Schmidt Interpreter class behavioral I ntent Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language Applicability – When the grammar is simple & relatively stable – Efficiency is not a critical concern Structure 61

  42. Pattern & Framework Tutorial Douglas C. Schmidt Interpreter class behavioral Consequences Known Uses + Simple grammars are easy to change & extend, e.g., • Text editors &Web all rules represented by distinct classes in an orderly browsers use manner Interpreter to lay + Adding another rule adds another class out documents & – Complex grammars are hard to implement & check spelling maintain, e.g., more interdependent rules yield more • For example, an interdependent classes equation in TeX is I mplementation represented as a • Express the language rules, one per class tree where internal nodes are • Alternations, repetitions, or sequences expressed as operators, e.g. nonterminal expresssions square root, & • Literal translations expressed as terminal expressions leaves are • Create interpret method to lead the context through variables the interpretation classes 62

  43. Pattern & Framework Tutorial Douglas C. Schmidt Builder object creational I ntent Separate the construction of a complex object from its representation so that the same construction process can create different representations Applicability – Need to isolate knowledge of the creation of a complex object from its parts – Need to allow different implementations/interfaces of an object's parts Structure 63

  44. Pattern & Framework Tutorial Douglas C. Schmidt Builder object creational Consequences Known Uses • ACE Service Configurator + Can vary a product's internal representation framework + Isolates code for construction & representation + Finer control over the construction process I mplementation • The Builder pattern is basically a Factory pattern with a mission • A Builder pattern implementation exposes itself as a factory, but goes beyond the factory implementation in that various implementations are wired together 64

  45. Pattern & Framework Tutorial Douglas C. Schmidt Summary of Tree Structure & Creation Patterns Interpreter < < use > > Expression_Tree_ Expression_Tree Interpreter_Context Context Interpreter < < create > > Component_Node Symbol Composite_ Composite_ Leaf_Node Number Operator Unary_Operator Binary_Node Unary_Node < < create > > Composite_ Composite_ Composite_ Add Substract Negate Add_Node Substract_Node Negate_Node Composite_ Composite_ Multiply Divide < < create > > Multiply_Node Divide_Node Composite Builder 65

  46. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Tree Traversal Patterns Visitor Iterator < < accept > > Expression_Tree Component_Node Visitor < < create > > Expression_Tree_ Expression_Tree_ Evaluation_Visitor Print_Visitor Iterator Iterator_Impl Level_Order_Expression_ LQueue Tree_Iterator_Impl In_Order_Expression_ Bridge std::stack Tree_Iterator_Impl Post_Order_Expression_ Tree_Iterator_Impl Pre_Order_Expression_ Tree_Iterator_Impl 66

  47. Pattern & Framework Tutorial Douglas C. Schmidt Encapsulating Variability & Simplifying Memory Managment Goals – Hide many sources of variability in expression tree construction & use – Simplify C+ + memory management, i.e., minimize use of new/delete in application code Constraints/ forces: – Must account for the fact that STL algorithms & iterators have “value semantics” for (Expression_Tree::iterator iter = tree.begin (); iter != tree.end (); ++iter) (*iter).accept (print_visitor); – Must ensure that exceptions don’t cause memory leaks 67

  48. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Decouple Interface & Implementation(s) Expression_Tree • Create a public interface class ( Expression_Tree ) used by clients & a private implementation hierarchy (rooted at Component_Node ) that encapsulates variability • The public interface class can perform reference counting of implementation object(s) to automate memory management • An Abstract Factory can produce the right implementation (as seen later) 68

  49. Pattern & Framework Tutorial Douglas C. Schmidt Expression_Tree Interface for Composite pattern used to contain all nodes in expression tree I nterface: Expression_Tree (void) Expression_Tree (Component_Node * root) Expression_Tree (const Expression_Tree &t) void operator= (const Expression_Tree &t) ~ Expression_Tree (void) Component_Node * get_root (void) bool is_null (void) const const int item (void) const Expression_Tree left (void) Expression_Tree right (void) iterator begin (const std::string &traversal_order) iterator end (const std::string &traversal_order) const_iterator begin (const std::string &traversal_order) const const_iterator end (const std::string &traversal_order) const Commonality : Provides a common interface for expression tree operations Variability : The contents of the expression tree nodes can vary depending on the expression 69

  50. Pattern & Framework Tutorial Douglas C. Schmidt Bridge object structural I ntent Separate a (logical) abstraction interface from its (physical) implementation(s) Applicability – When interface & implementation should vary independently – Require a uniform interface to interchangeable class hierarchies Structure 70

  51. Pattern & Framework Tutorial Douglas C. Schmidt Bridge object structural Consequences + abstraction interface & implementation are independent + implementations can vary dynamically + Can be used transparently with STL algorithms & containers – one-size-fits-all Abstraction & Implementor interfaces I mplementation • sharing Implementors & reference counting • See reusable Refcounter template class (based on STL/boost shared_pointer ) • creating the right Implementor (often use factories) Known Uses • ET+ + Window/WindowPort • libg+ + Set/{ LinkedList, HashTable} • AWT Component/ComponentPeer 71

  52. Pattern & Framework Tutorial Douglas C. Schmidt Tree Printing & Evaluation Goals: Algo 1: Print all Algo 2: Evaluate – Create a framework for the values of the the “yield” of the performing algorithms that nodes in the tree nodes in the tree affect nodes in a tree Constraints/ forces: Binary Nodes – support multiple algorithms that can act on the expression tree – don’t tightly couple algorithms with expression tree structure Unary Node – e.g., don’t have “print” & “evaluate” methods in the node classes Leaf Nodes 72

  53. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Encapsulate Traversal I terator – encapsulates a traversal algorithm without exposing representation details to callers e.g., – “in-order iterator” = -5* (3+ 4) – “pre-order iterator” = * -5+ 34 Unary – “post-order iterator” = 5-34+ * Node – “level-order iterator” = * -+ 534 Leaf Expression_Tree_Iterator Expression_Tree_Iterator_Impl Nodes In_Order_Expression_Tree_Iterator_Impl Post_Order_Expression_Tree_Iterator_Impl Level_Order_Expression_Tree_Iterator_Impl Pre_Order_Expression_Tree_Iterator_Impl 73 Note use of the Bridge pattern to encapsulate variability

  54. Pattern & Framework Tutorial Douglas C. Schmidt Expression_Tree_Iterator Interface for Iterator pattern that traverses all nodes in tree expression I nterface: Expression_Tree_Iterator (const Expression_Tree_Iterator &) Expression_Tree_Iterator (Expression_Tree_Iterator_Impl * ) Expression_Tree operator * (void) const Expression_Tree operator * (void) const Expression_Tree_Iterator & operator+ + (void) Expression_Tree_Iterator operator+ + (int) bool operator= = (const Expression_Tree_Iterator &rhs) bool operator!= (const Expression_Tree_Iterator &rhs) Commonality : Provides a common interface for expression tree iterators that conforms to the standard STL iterator interface Variability : Can be configured with specific expression tree iterator algorithms via the Bridge & Abstract Factory patterns 74 See Expression_Tree_State.cpp for example usage

  55. Pattern & Framework Tutorial Douglas C. Schmidt Expression_Tree_Iterator_Impl Implementation of the Iterator pattern that is used to define the various iterations algorithms that can be performed to traverse the expression tree I nterface: Expression_Tree_Iterator_Impl (const Expression_Tree &tree) virtual ~ Expression_Tree_Iterator_Impl (void) virtual Expression_Tree operator * (void) = 0 virtual const Expression_Tree operator * (void) const = 0 virtual void operator+ + (void)= 0 virtual bool operator= = (const Expression_Tree_Iterator_Impl &rhs) const = 0 virtual bool operator!= (const Expression_Tree_Iterator_Impl &rhs) const = 0 virtual Expression_Tree_Iterator_Impl * clone (void)= 0 Commonality : Provides a common interface for implementing expression tree iterators that conforms to the standard STL iterator interface Variability : Can be subclasses to define various algorithms for accessing nodes in the expression trees in a particular traversal order 75

  56. Pattern & Framework Tutorial Douglas C. Schmidt Iterator object behavioral I ntent access elements of a aggregate (container) without exposing its representation Applicability – require multiple traversal algorithms over an aggregate – require a uniform traversal interface over different aggregates – when aggregate classes & traversal algorithm must vary independently Structure 76

  57. Pattern & Framework Tutorial Douglas C. Schmidt Comparing STL Iterators with GoF Iterators STL iterators have “value-semantics”, e.g.: for (Expression_Tree::iterator iter = tree.begin (”Level Order”); iter != tree.end (”Level Order”); ++iter) (*iter).accept (print_visitor); In contrast, “GoF iterators have “pointer semantics”, e.g.: iterator *iter; for (iter = tree.createIterator (”Level Order”); iter->done () == false; iter->advance ()) (iter->currentElement ())->accept (print_visitor); delete iter; Bridge pattern simplifies use of STL iterators in expression tree application 77

  58. Pattern & Framework Tutorial Douglas C. Schmidt Iterator object behavioral Consequences Known Uses • C+ + STL iterators + flexibility: aggregate & traversal are independent • JDK Enumeration, + multiple iterators & multiple traversal algorithms Iterator – additional communication overhead between • Unidraw Iterator iterator & aggregate – This is particularly problematic for iterators in concurrent or distributed systems I mplementation • internal versus external iterators • violating the object structure’s encapsulation • robust iterators • synchronization overhead in multi-threaded programs • batching in distributed & concurrent programs 78

  59. Pattern & Framework Tutorial Douglas C. Schmidt Visitor • Defines action(s) at each step of traversal & avoids wiring action(s) in nodes • Iterator calls nodes’s accept(Visitor) at each node, e.g.: void Leaf_Node::accept (Visitor &v) { v.visit (*this); } • accept() calls back on visitor using “static polymorphism” I nterface: virtual void visit (const Leaf_Node &node)= 0 virtual void visit (const Composite_Negate_Node &node)= 0 virtual void visit (const Composite_Add_Node &node)= 0 virtual void visit (const Composite_Subtract_Node &node)= 0 virtual void visit (const Composite_Divide_Node &node)= 0 virtual void visit (const Composite_Multiply_Node &node)= 0 Commonality : Provides a common accept () method for all expression tree nodes & common visit() method for all visitor subclasses Variability : Can be subclassed to define specific behaviors for the visitors & nodes 79

  60. Pattern & Framework Tutorial Douglas C. Schmidt Print_Visitor • Prints character code or value for each node class Print_Visitor : public Visitor { public: virtual void visit (const Leaf_Node &); virtual void visit (const Add_Node &); virtual void visit (const Divide_Node &); // etc. for all relevant Component_Node subclasses }; • Can be combined with any traversal algorithm, e.g.: Print_Visitor print_visitor; for (Expression_Tree::iterator iter = tree.begin (”post-order”); iter != tree.end (”post-order”); ++iter) (*iter).accept (print_visitor); // calls visit (*this); 80 See Expression_Tree_State.cpp for example usage

  61. Pattern & Framework Tutorial Douglas C. Schmidt Print_Visitor Interaction Diagram • The iterator controls the order in which accept() is called on each node in the composition • accept() then “visits” the node to perform the desired print action Leaf_Node (5) Composite_Negate_Node print_visitor accept(print_visitor) cout<< node.item (); accept(print_visitor) cout<< ‘-’ 81

  62. Pattern & Framework Tutorial Douglas C. Schmidt Evaluation_Visitor • This class serves as a visitor for class Evaluation_Visitor : evaluating nodes in an expression public Visitor { /* ... */ }; tree that is being traversed using a post-order iterator – e.g., 5-34+ * • It uses a stack to keep track of the post- order expression tree value that has been processed thus far during the iteration traversal, e.g.: 1. S = [5] push(node.item()) 2. S = [-5] push(-pop()) Unary 3. S = [-5, 3] push(node.item()) Node 4. S = [-5, 3, 4] push(node.item()) 5. S = [-5, 7] push(pop()+pop()) Leaf 6. S = [-35] push(pop()*pop()) Nodes 82

  63. Pattern & Framework Tutorial Douglas C. Schmidt Evaluation_Visitor Interaction Diagram • The iterator controls the order in which accept() is called on each node in the composition • accept() then “visits” the node to perform the desired evaluation action Leaf_Node (5) Composite_Negate_Node eval_visitor accept(eval_visitor) stack_.push(node.item ()); accept(eval_visitor) stack_.push(-stack_.pop()); 83

  64. Pattern & Framework Tutorial Douglas C. Schmidt Visitor object behavioral I ntent Centralize operations on an object structure so that they can vary independently but still behave polymorphically Applicability – when classes define many unrelated operations – class relationships of objects in the structure rarely change, but the operations on them change often – algorithms keep state that’s updated during traversal Structure Note “static polymorphism” based on method overloading by type 84

  65. Pattern & Framework Tutorial Douglas C. Schmidt Visitor object behavioral Consequences + flexibility: visitor algorithm(s) & object structure are independent + localized functionality in the visitor subclass instance – circular dependency between Visitor & Element interfaces – Visitor brittle to new ConcreteElement classes I mplementation • double dispatch • general interface to elements of object structure Known Uses • ProgramNodeEnumerator in Smalltalk-80 compiler • IRIS Inventor scene rendering • TAO IDL compiler to handle different backends 85

  66. Pattern & Framework Tutorial Douglas C. Schmidt Summary of Tree Traversal Patterns Visitor Iterator < < accept > > Expression_Tree Component_Node Visitor < < create > > Expression_Tree_ Expression_Tree_ Evaluation_Visitor Print_Visitor Iterator Iterator_Impl Level_Order_Expression_ LQueue Tree_Iterator_Impl In_Order_Expression_ Bridge std::stack Tree_Iterator_Impl Post_Order_Expression_ Tree_Iterator_Impl Pre_Order_Expression_ Tree_Iterator_Impl 86

  67. Pattern & Framework Tutorial Douglas C. Schmidt Overview of Command & Factory Patterns AbstractFactory Expression_Tree_ Expression_Tree_ Expression_Tree_Command_ Event_Handler Command_Factory Factory_Impl Concrete_Expression_Tree_ Expression_Tree_ < < create > > Command_Factory_Impl Context Expression_Tree_ Expression_Tree_ * Command Command_Impl 1 Macro_Command Print_Command Set_Command Quit_Command Null_Command Format_Command Expr_Command Eval_Command Command 87

  68. Pattern & Framework Tutorial Douglas C. Schmidt Consolidating User Operations Goals: % tree-traversal -v – support execution of format [in-order] user operations expr [expression] – support macro print [in-order|pre-order|post-order|level-order] commands eval [post-order] – support undo/redo quit > format in-order Constraints/ forces: > expr 1+ 2* 3/2 – scattered operation > print in-order implementations 1+ 2* 3/2 – Consistent memory > print pre-order management + 1/* 232 > eval post-order 4 > quit 88

  69. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Encapsulate Each Request w/Command A Command encapsulates Command may  implement the operations  an operation ( execute() ) itself, or  an inverse operation ( unexecute() )  delegate them to other  a operation for testing reversibility object(s) ( boolean reversible() )  state for (un)doing the operation Expression_Tree_Command Expression_Tree_Command_Impl Format_Command Print_Command Eval_Command Quit_Command Expr_Command Macro_Command Note use of Bridge pattern to encapsulate variability & simplify memory management 89

  70. Pattern & Framework Tutorial Douglas C. Schmidt Expression_Tree_Command Interface for Command pattern used to define a command that performs an operation on the expression tree when executed I nterface: Expression_Tree_Command (Expression_Tree_Command_Impl * = 0) Expression_Tree_Command (const Expression_Tree_Command &) Expression_Tree_Command & operator= (const Expression_Tree_Command &) ~ Expression_Tree_Command (void) bool execute (void) boolunexecute (void) Commonality : Provides a common interface for expression tree commands Variability : The implementations of the expression tree commands can vary depending on the operations requested by user input 90

  71. Pattern & Framework Tutorial Douglas C. Schmidt List of Commands = Execution History unexecute() unexecute() unexecute() execute() Undo: Redo: cmd cmd cmd cmd past future future past 91

  72. Pattern & Framework Tutorial Douglas C. Schmidt Command object behavioral I ntent Encapsulate the request for a service Applicability – to parameterize objects with an action to perform – to specify, queue, & execute requests at different times – for multilevel undo/redo Structure 92

  73. Pattern & Framework Tutorial Douglas C. Schmidt Command object behavioral Consequences Known Uses • InterViews Actions + abstracts executor of a service • MacApp, Unidraw Commands + supports arbitrary-level undo-redo • JDK’s UndoableEdit, + composition yields macro-commands AccessibleAction – might result in lots of trivial command • Emacs subclasses • Microsoft Office tools – excessive memory may be needed to support undo/redo operations I mplementation • copying a command before putting it on a history list • handling hysteresis • supporting transactions 93

  74. Pattern & Framework Tutorial Douglas C. Schmidt Consolidating Creation of Variabilities Goals: Constraints/ forces: – Simplify & centralize the creation of all – Don’t recode variabilities in the expression tree existing clients application to ensure semantic compatibility – Add new variabilities – Be extensible for future variabilities without recompiling Expression_Tree_Command Expression_Tree_Command_Impl Format_Command Print_Command Eval_Command Quit_Command Expr_Command Macro_Command Expression_Tree_Iterator Expression_Tree_Iterator_Impl In_Order_Expression_Tree_Iterator_Impl Post_Order_Expression_Tree_Iterator_Impl Level_Order_Expression_Tree_Iterator_Impl Pre_Order_Expression_Tree_Iterator_Impl 94

  75. Pattern & Framework Tutorial Douglas C. Schmidt Solution: Abstract Object Creation Instead of Expression_Tree_Command command = new Print_Command (); Use Expression_Tree_Command command = command_factory.make_command (“print”); where command_factory is an instance of Expression_Tree_Command_Factory or anything else that makes sense wrt our goals Expression_Tree_Command_Factory Expression_Tree_Command_Factory_Impl Concrete_Expression_Tree_ Command_Factory_Impl 95

  76. Pattern & Framework Tutorial Douglas C. Schmidt Expression_Tree_Command_Factory Interface for Abstract Factory pattern used to create appropriate command based on string supplied by caller Expression_Tree_Command_Factory I nterface: (Expression_Tree_Context &tree_context) Expression_Tree_Command_Factory (const Expression_Tree_Command_Factory &f) void operator= (const Expression_Tree_Command_Factory &f) ~ Expression_Tree_Command_Factory (void) Expression_Tree_Command make_command (const std::string &s) Expression_Tree_Command make_format_command (const std::string &) Expression_Tree_Command make_expr_command (const std::string &) Expression_Tree_Command make_print_command (const std::string &) Expression_Tree_Command make_eval_command (const std::string &) Expression_Tree_Command make_quit_command (const std::string &) Expression_Tree_Command make_macro_command (const std::string &) Commonality : Provides a common interface to create commands Variability : The implementations of the expression tree command factory methods can vary depending on the requested commands 96

  77. Pattern & Framework Tutorial Douglas C. Schmidt Factory Structure Expression_Tree_Command_ Factory Expression_Tree_Command Expression_Tree_Command_ Factory_Impl Expression_Tree_Command_Impl Concrete_Expression_Tree_ Command_Factory_Impl Format_Command make_format_command() Expr_Command make_expr_command() make_print_command() Print_Command make_eval_command() Eval_Command make_macro_command() Macro_Command make_quit_command() Quit_Command Note use of Bridge pattern to encapsulate variability & simplify memory management 97

  78. Pattern & Framework Tutorial Douglas C. Schmidt Factory Method class creational I ntent Provide an interface for creating an object, but leave choice of object’s concrete type to a subclass Applicability when a class cannot anticipate the objects it must create or a class wants its subclasses to specify the objects it creates Structure 98

  79. Pattern & Framework Tutorial Douglas C. Schmidt Factory Method class creational Consequences Known Uses + By avoiding to specify the class name of the • InterViews Kits concrete class &the details of its creation the • ET+ + client code has become more flexible WindowSystem + The client is only dependent on the interface • AWT Toolkit - Construction of objects requires one additional • The ACE ORB (TAO) class in some cases • BREW I mplementation • UNIX open() syscall • There are two choices here • The creator class is abstract & does not implement creation methods (then it must be subclassed) • The creator class is concrete & provides a default implementation (then it can be subclassed) • Should a factory method be able to create different variants? If so the method must be equipped with a parameter 99

  80. Pattern & Framework Tutorial Douglas C. Schmidt Abstract Factory object creational I ntent create families of related objects without specifying subclass names Applicability when clients cannot anticipate groups of classes to instantiate Structure See Uninitialized_State_Factory & Expression_Tree_Event_Handler for Factory pattern variants 100

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend