Design Pattern Case Studies with C++ Douglas C. Schmidt Http

Design Pattern Case Studies with C++ Douglas C. Schmidt Http

Case Studies Using Patterns The following slides describ e several case Design Pattern Case Studies with studies using C++ and patterns to build highly extensible software C++ The examples include 1. Expression trees Douglas C. Schmidt { e.g., Bridge, Factory, Adapter 2. System Sort http://www.cs.wustl.edu/schmidt/ { e.g., Facade, Adapter, Iterator, Singleton, [email protected] Factory Metho d, Strategy, Bridge, Double- Checked Lo cking Optimization Washington University, St. Louis 3. Sort Veri er { e.g., Strategy, Factory Metho d, Facade, It- erator, Singleton 2 1 Case Study 1: Expression Tree Expression Tree Diagram Evaluator BINARY The following inheritance and dynamic bind- NODES example constructs expression trees ing * { Expression trees consist of no des containing op erators and op erands _ Op erators have di erent precedence levels, + di erent asso ciativities, and di erent arities, e.g., Multiplication takes precedence over addi- UNARY tion NODE 55 33 44 The multiplication op erator has two argu- ments, whereas unary minus op erator has only one Op erands are integers, doubles, variables, INTEGER etc. NODES We'll just handle integers in this example::: 3 4 C Version Expression Tree Behavior A typical functional metho d for implement- ing expression trees in C involves using a struct/union to represent data structure, Expression trees e.g., { Trees may be \evaluated" via di erent traver- sals typ edef struct Tree No de Tree No de; struct Tree No de f e.g., in-order, p ost-order, pre-order, level- enum f order NUM, UNARY, BINARY ; g tag { The evaluation step may p erform various op- short use ; /* reference count */ erations, e.g., union f ; int num Traverse and print the expression tree char op [2]; g o; de ne num o.num Return the \value" of the expression tree de ne op o.op union f Generate co de Tree No de *unary ; struct f Tree No de *l , *r ; g binary ; Perform semantic analysis g c; de ne unary c.unary de ne binary c.binary g; 5 6 Memory Layout of C Version Print Tree Function tag_ Typical C implementation cont'd use_ Use a switch statement and a recursive func- Tree { op_ to build and evaluate a tree, e.g., Node tion num_ 1|2 tree Tree No de *ro ot f void print switch ro ot->tag f ; break; case NUM: printf "d", ro ot->num UNARY: unary_ 1 case printf "s", ro ot->op [0]; tree ro ot->unary ; rint Tree p printf ""; break; BINARY: binary_ Node case printf ""; tree ro ot->binary .l ; print rintf "s", ro ot->op [0]; MEMORY CLASS p rint tree ro ot->binary .r ; LAYOUT RELATIONSHIPS p printf ""; break; default: printf "error, unknown typ e\n"; exit 1; g Here's what the memory layout of a struct g Tree No de object lo oks like 7 8 Limitations with C Approach More Limitations with C Problems or limitations with the typical C approach include Approach { Language feature limitations in C The program organization makes it di- e.g., no supp ort for inheritance and dynamic cult to extend, e.g., binding { Any small changes will ripple through the entire design and implementation { Incomplete mo deling of the application domain, which results in e.g., see the \ternary" extension b elow 1. Tight coupling between no des and edges in union representation { Easy to make mistakes switching on typ e tags::: 2. Complexity b eing in algorithms rather than the data structures Solution wastes space by making worst- case assumptions wrt structs and unions e.g., switch statements are used to select between various typ es of no des in the ex- { This is not essential, but typically o ccurs pression trees compare with binary search! { Note that this problem b ecomes worse the big- ger the size of the largest item b ecomes! Data structures are \passive" and func- tions do most pro cessing work explicitly 9 10 OO Alternative Relationships Between Trees and Contrast previous functional approach with an object-oriented decomp osition for the No des same problem: { Start with OO mo deling of the \expression application domain: tree" Binary Unary Int Node Node Node e.g., go back to original picture 1 1 { There are several classes involved: class No de: base class that describ es expression tree vertices: No de: used for implicitly class Int converting int to Tree no de No de: handles unary op erators, Unary class Ternary Node , 10, +10, !a, or ~fo o, etc. e.g. Node 1 No de: handles binary op erators, Binary class 2 , a + b, 10 30, etc. e.g. 1 Tree: \glue" co de that describ es class Tree ression tree edges exp 3 { Note, these classes mo del elements in the ap- plication domain i.e., no des and edges or vertices and arcs 11 12 Design Patterns in the Expression C++ No de Interface Tree Program // No de.h Adapter NODE H if !de ned { \Convert the interface of a class into another de ne NODE H interface clients exp ect" class Tree; // Forward decl e.g., make Tree conform to interfaces ex- // Describ es the Tree vertices p ected by C++ iostreams op erators class No de f friend class Tree; Factory protected: // Only visible to derived classes No de void { \Centralize the assembly of resources neces- 1 fg : use sary to create an object" e.g., decouple Node sub class initialization from // pure virtual their subsequent use virtual void print ostream & const = 0; // Imp ortant to make destructor virtual! Bridge virtual ~No de void; { \Decouple an abstraction from its implemen- private: tation so that the two can vary indep endently" int use ; // Reference counter. g; e.g., printing the contents of a subtree endif /* NODE H */ 13 14 C++ Int No de and Unary No de C++ Tree Interface Interface // Int No de.h // Tree.h include "No de.h" include "No de.h" class Int No de : public No de f // Describ es the Tree edges and acts as a Factory public: class Tree f Int No de int k; public: virtual void print ostream &stream const; // Factory op erations private: Tree int; int num ; // op erand value. Tree const char *, Tree &; g; Tree const char *, Tree &, Tree &; // Unary No de.h Tree const Tree &t; // Copy constructor void op erator= const Tree &t; // Assignment include "No de.h" ~Tree void; // Destructor class Unary No de : public No de f void print ostream & const; public: Unary No de const char *op, const Tree &t; private: virtual void print ostream &stream const; No de *no de ; // p ointer to a ro oted subtree. private: g; const char *op eration ; ; Tree op erand g; 15 16 Memory Layout for C++ Version NodeNode NodeNode NodeNode PARTPART PARTPART PARTPART node_ptr C++ Binary No de Interface tagtag Tree operator_operator operator_operator operator_operator opop No de.h // Binary vptrvptr operand_operand left_left left_left include "No de.h" (Tree(Tree PARTPART)) (Tree(Tree PARTPART)) (Tree(Tree PARTPART)) use_use class Binary : public No de f No de Node Unary Node public: right_ No de const char *op, ry Bina right middle_middle (Tree(Tree PARTPART)) (Tree(Tree PARTPART)) Tree &t1, const NodeNode Tree &t2; const PARTPART void print ostream &s const; virtual Binary rivate: p Node num_ num right_ ; char *op eration const right (Tree(Tree PARTPART)) Tree left ; Int_Node Ternary Tree right ; Node g; Memory layouts for di erent sub classes of Node 17 18 C++ Int No de and Unary No de Implementations C++ Binary No de // Int No de.C Implementation No de.h" include "Int // Binary No de.C Int No de::Int No de int k: num k f g include "Binary No de.h" void Int No de::print ostream &stream const f stream << this->num ; No de::Binary No de const char *op, Binary g const Tree &t1, const Tree &t2: op eration op, left t1, right t2 // Unary No de.C f g include "Unary No de.h" void Binary No de::print ostream &stream const f stream << "" << this->left // recursive call Unary No de::Unary No de const char *op, const Tree &t1 << " " << this->op eration : op eration op, op erand t1 f g << " " << this->right // recursive call << ""; void Unary No de::print ostream &stream const f g stream << "" << this->op eration << " " << this->op erand // recursive call! << ""; g 19 20 The Factory Pattern Initializing the No de Sub classes Intent Problem { \Centralize the assembly of resources neces- { How to ensure the No de sub classes are initial- sary to create an object" ized prop erly Decouple object creation from object use by lo calizing creation knowledge Forces { There are di erent typ es of No de sub classes This pattern resolves the following forces: e.g., take di erent numb er and typ e of ar- { Decouple initialization of the Node sub classes guments from their subsequent use { We want to centralize initialization in one place { Makes it easier to change or add new No de b ecause it is likely to change::: sub classes later on e.g., Ternary no des::: Solution { Use a Factory pattern to initialize the No de sub classes A variant of the Factory Metho d 22 21 Structure of the Factory Pattern the Factory Pattern Factory Using The Factory pattern is used by the Tree make_product() class to initialize No de sub classes: ree::Tree int num creates T : no de new Int No de num fg ree::Tree const char *op, const Tree &t Product product = ... T no de new Unary No de op, t fg return product : Tree::Tree const char *op, const Tree &t1, Tree &t2: Product const : no de new Binary No de op, t1, t2 fg 24 23 Printing Subtrees The Bridge Pattern Problem Intent { How do we print subtrees without revealing { \Decouple an abstraction from its implemen- their typ es? tation so that the two can vary indep endently" Forces This pattern resolves the following forces that arise when building extensible soft- { The Node sub class should be hidden within the ware with C++ Tree instances 1.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    32 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us