Download presentation
Presentation is loading. Please wait.
Published byByron Allen Modified over 9 years ago
1
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style ADVANCED PROGRAM DESIGN WITH C++ Design patterns Joey Paquet, 2007-2014 1COMP 345 - Advanced Program Design with C++
2
Concordia University Department of Computer Science and Software Engineering “Each 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.” [Christopher Alexander – late 1970s] A Pattern Language (1977) A Timeless Way of Building (1979) Design patterns capture the best practices of experienced object-oriented software developers. Design patterns are solutions to general software development problems. Design patterns Joey Paquet, 2007-2014 2COMP 345 - Advanced Program Design with C++
3
Concordia University Department of Computer Science and Software Engineering In general, a pattern has four essential elements. The pattern name The problem The solution The consequences Pattern elements Joey Paquet, 2007-2014 3COMP 345 - Advanced Program Design with C++
4
Concordia University Department of Computer Science and Software Engineering The pattern name is a handle we can use to describe a design problem, its solutions, and consequences in a word or two. Naming a pattern immediately increases the design vocabulary. It lets us design at a higher level of abstraction. Having a vocabulary for patterns lets us talk about them. It makes it easier to think about designs and to communicate them and their trade-offs to others. Pattern elements: name Joey Paquet, 2007-2014 4COMP 345 - Advanced Program Design with C++
5
Concordia University Department of Computer Science and Software Engineering The problem describes when to apply the pattern. It explains the problem and its context. It might describe specific design problems such as how to represent algorithms as objects. It might describe class or object structures that are symptomatic of an inflexible design. Sometimes the problem will include a list of conditions that must be met before it makes sense to apply the pattern. Pattern elements: problem Joey Paquet, 2007-2014 5COMP 345 - Advanced Program Design with C++
6
Concordia University Department of Computer Science and Software Engineering The solution describes the elements that make up the design, their relationships, responsibilities, and collaborations. The solution doesn't describe a particular concrete design or implementation, because a pattern is like a template that can be applied in many different situations. Instead, the pattern provides an abstract description of a design problem and how a general arrangement of elements (classes and objects in our case) solves it. Pattern elements: solution Joey Paquet, 2007-2014 6COMP 345 - Advanced Program Design with C++
7
Concordia University Department of Computer Science and Software Engineering The consequences are the results and trade-offs of applying the pattern. The consequences for software often concern space and time trade- offs. They may address language and implementation issues as well. Since reuse is often a factor in object-oriented design, the consequences of a pattern include its impact on a system's flexibility, extensibility, or portability. Pattern elements: consequences Joey Paquet, 2007-2014 7COMP 345 - Advanced Program Design with C++
8
Concordia University Department of Computer Science and Software Engineering Erich Gamma, Richard Helm, Ralph Johnson and John Vlisides in their Design Patterns [gang of four] book define 23 design patterns divided into three types: Creational patterns - create objects for you, rather than having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case. Structural patterns - help you compose groups of objects into larger structures, such as complex user interfaces or accounting data. Behavioral patterns - help you define the communication between objects in your system and how the flow is controlled in a complex program. Design pattern: types Joey Paquet, 2007-2014 8COMP 345 - Advanced Program Design with C++
9
Concordia University Department of Computer Science and Software Engineering The creational patterns deal with the best way to create instances of objects. In C++, the simplest ways to create an instance of an object is by using the new operator or by simply declaring the variable in the local scope: Fred* fred1 = new Fred(); //instance of Fred class Fred fred2; //instance of Fred class The amount of hard coding depends on how you create the object within your program. In many cases, the exact nature of the object that is created could vary with the needs of the program and abstracting the creation process into a special “creator” class can make your program more flexible and general. Creational patterns: concept Joey Paquet, 2007-2014 9COMP 345 - Advanced Program Design with C++
10
Concordia University Department of Computer Science and Software Engineering The Factory Pattern provides a simple decision making class that returns one of several possible subclasses of an abstract base class depending on the data that are provided. The Abstract Factory Pattern provides an interface to create and return one of several families of related objects. The Builder Pattern separates the construction of a complex object from its representation. The Prototype Pattern starts with an initialized and instantiated class and copies or clones it to make new instances rather than creating new instances. The Singleton Pattern is a class of which there can be no more than one instance. It provides a single global point of access to that instance. Creational patterns: examples Joey Paquet, 2007-2014 10COMP 345 - Advanced Program Design with C++
11
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style Factory pattern Joey Paquet, 2007-2014 11COMP 345 - Advanced Program Design with C++
12
Concordia University Department of Computer Science and Software Engineering The Factory pattern returns an instance of one of several possible classes depending on the data provided to it. Here, x is a base class and classes xy and xz are derived from it. The Factory is a class that decides which of these subclasses to return depending on the arguments you give it. The getClass() method passes in some value abc, and returns some instance of one of the subclasses of the class x. Which one it returns doesn't matter to the programmer since they all have the same methods, but different implementations. This is supposing that the object produced will be used polymorphically. Factory pattern Joey Paquet, 2007-2014 12COMP 345 - Advanced Program Design with C++
13
Concordia University Department of Computer Science and Software Engineering Factory pattern: example Joey Paquet, 2007-2014 13COMP 345 - Advanced Program Design with C++ class ShapeFactory { public: // Static method to create objects // Change is required only in this function static Shape* Create(string type){ if ( type == "circle" ) return new Circle(); if ( type == "square" ) return new Square(); return NULL;} private: //Constructor is made private to prevent instantiation ShapeFactory(){}; };
14
Concordia University Department of Computer Science and Software Engineering Factory pattern: example Joey Paquet, 2007-2014 14COMP 345 - Advanced Program Design with C++ //Superclass of all object that the Factory can create class Shape { public: //common interface to all subtypes virtual void draw() = 0; }; class Circle : public Shape { public: void draw() { cout << "I am circle" << endl; } }; class Square : public Shape { public: void draw() { cout << "I am square" << endl; } };
15
Concordia University Department of Computer Science and Software Engineering Factory pattern: example Joey Paquet, 2007-2014 15COMP 345 - Advanced Program Design with C++ int main() { // Give me a circle Shape* shape1 = ShapeFactory::Create("circle"); // Give me a square Shape* shape2 = ShapeFactory::Create("square"); shape1->draw(); // will call appropriate draw() shape2->draw(); // as it is defined as virtual delete shape1; delete shape2; }
16
Concordia University Department of Computer Science and Software Engineering You should consider using a Factory pattern when: Various kinds of objects are to be used polymorphically. A class uses a hierarchy of classes to specify which objects it creates. A class can’t anticipate the kind of objects it must create. You want to localize the knowledge of which class gets created. How to recognize variations of the Factory pattern? The base class is (most often) abstract. The base class contains default methods and is only subclassed for cases where the default methods are insufficient. Parameters are passed to the factory telling it which of several class types to return. Classes may share the same method names but may do something quite different. Also often called a “factory method”. Factory pattern: context Joey Paquet, 2007-2014 16COMP 345 - Advanced Program Design with C++
17
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style Abstract factory pattern Joey Paquet, 2007-2014 17COMP 345 - Advanced Program Design with C++
18
Concordia University Department of Computer Science and Software Engineering The Abstract Factory pattern is one level of abstraction higher than the factory pattern. This pattern returns one of several related classes, each of which can return several different objects on request. In other words, the Abstract Factory is a factory object that returns one of several factories. One classic application of the abstract factory is the case where your system needs to support multiple “look-and-feel” user interfaces, such as Windows, Linux or Macintosh: You tell the factory that you want your program to look like Windows and it returns a GUI factory which returns Windows-like objects. When you request specific objects such as buttons, check boxes and windows, the GUI factory returns Windows instances of these visual interface components. Abstract factory Joey Paquet, 2007-2014 18COMP 345 - Advanced Program Design with C++
19
Concordia University Department of Computer Science and Software Engineering Abstract factory: example Joey Paquet, 2007-2014 19COMP 345 - Advanced Program Design with C++ // Superclass of all objects to be created by all Factories class Widget { public: //common interface to all created objects virtual void draw() = 0; }; //Supeclass of all Factories class WidgetFactory { public: //All specific kinds of objects that can be created virtual Widget* create_button() = 0; virtual Widget* create_menu() = 0; };
20
Concordia University Department of Computer Science and Software Engineering Abstract factory: example Joey Paquet, 2007-2014 20COMP 345 - Advanced Program Design with C++ //Factory generating Motif Widgets class CocoaWidgetFactory : public WidgetFactory { public: Widget* create_button() { return new CocoaButton; } Widget* create_menu() { return new CocoaMenu; } }; //Different specific kinds of Motif objects class CocoaButton : public Widget { public: void draw() { cout << "CocoaButton\n"; } }; class CocoaMenu : public Widget { public: void draw() { cout << "CocoaMenu\n"; } };
21
Concordia University Department of Computer Science and Software Engineering Abstract factory: example Joey Paquet, 2007-2014 21COMP 345 - Advanced Program Design with C++ //Factory generating Windows MFC Widgets class MFCWidgetFactory : public WidgetFactory { public: Widget* create_button() { return new MFCButton; } Widget* create_menu() { return new MFCMenu; } }; //Different specific kinds of Windows MFC objects class MFCButton : public Widget { public: void draw() { cout << “MFCButton\n"; } }; class MFCMenu : public Widget { public: void draw() { cout << “MFCMenu\n"; } };
22
Concordia University Department of Computer Science and Software Engineering Abstract factory: example Joey Paquet, 2007-2014 22COMP 345 - Advanced Program Design with C++ //uncomment the following to generate Cocoa widgets #define OSX //uncomment the following to generate MFC widgets //#define WINDOWS int main(int argc, char *argv[]) { WidgetFactory *widget_factory; #ifdef MOTIF widget_factory = new CocoaWidgetFactory; #else // WINDOWS widget_factory = new MFCWidgetFactory; #endif Widget* w[2] = {widget_factory->create_button(), widget_factory->create_menu()}; w[0]->draw(); //call appropriate draw() method w[1]->draw(); //of subclass of Widget object }
23
Concordia University Department of Computer Science and Software Engineering One of the main purposes of the Abstract Factory is that it abstracts the concrete classes from which the objects are instantiated. The actual class names of these classes are hidden in the factory and need not be known at the client level at all. Because of the isolation of classes, you can change or interchange these product class families freely. Since you generate only one kind of concrete class, this system keeps you for inadvertently using classes from different families of products. Abstract factory: consequences Joey Paquet, 2007-2014 23COMP 345 - Advanced Program Design with C++
24
Concordia University Department of Computer Science and Software Engineering Requires the use of polymorphic design. While all of the classes that the Abstract Factory generates have the same base class, there is nothing to prevent some derived classes from having additional methods that differ from the methods of other classes. This may lead to more complex use though. Often used in conjunction with the adapter pattern to have similar classes to expose the same interface. Abstract factory: consequences Joey Paquet, 2007-2014 24COMP 345 - Advanced Program Design with C++
25
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style Builder pattern Joey Paquet, 2007-2014 25COMP 345 - Advanced Program Design with C++
26
Concordia University Department of Computer Science and Software Engineering The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. Builder - specifies an abstract interface for creating parts of a Product object. ConcreteBuilder - constructs and assembles parts of the product by implementing the Builder interface. Also, it defines and keeps track of the representation it creates and provides an interface for retrieving the product. Director - constructs an object using the Builder interface. Product - represents the complex object under construction. Builder pattern Joey Paquet, 2007-2014 26COMP 345 - Advanced Program Design with C++
27
Concordia University Department of Computer Science and Software Engineering The following interaction diagram illustrates how Builder and Director cooperate with a client. The client creates the Director object and configures it with the desired Builder object. Director notifies the builder whenever a part of the product should be built. Builder handles requests from the director and adds parts to the product. The client retrieves the product from the builder. Builder pattern Joey Paquet, 2007-2014 27COMP 345 - Advanced Program Design with C++
28
Concordia University Department of Computer Science and Software Engineering Builder pattern: example Joey Paquet, 2007-2014 28COMP 345 - Advanced Program Design with C++ //Superclass of all kinds of objects to be created //Generically called “Product” class Pizza { public: //Set all parts of the Product, and use the Product void setDough(const string& dough){ m_dough = dough;} void setSauce(const string& sauce){ m_sauce = sauce;} void setTopping(const string& topping){ m_topping = topping;} void open() const{ cout << "Pizza with " << m_dough << " dough, " << m_sauce << " sauce and " << m_topping << " topping. Mmm." << endl;} private: //Parts of the Product string m_dough; string m_sauce; string m_topping; };
29
Concordia University Department of Computer Science and Software Engineering Builder pattern: example Joey Paquet, 2007-2014 29COMP 345 - Advanced Program Design with C++ class PizzaBuilder { public: //get the built Pizza from the Builder Pizza* getPizza(){ return m_pizza; } //build a generic empty Pizza void createNewPizzaProduct(){ m_pizza = new Pizza; } //create each part of the Product according to subtypes virtual void buildDough() = 0; virtual void buildSauce() = 0; virtual void buildTopping() = 0; protected: //Product built by Pizza Builder Pizza* m_pizza; };
30
Concordia University Department of Computer Science and Software Engineering Builder pattern: example Joey Paquet, 2007-2014 30COMP 345 - Advanced Program Design with C++ class HawaiianPizzaBuilder : public PizzaBuilder //Concrete Builder 1 { public: virtual void buildDough() //Build different parts of the pizza {m_pizza->setDough("cross");} //The construction process could be virtual void buildSauce() //more complex in a real-life example {m_pizza->setSauce("mild");} //The construction of the pizza part virtual void buildTopping() //depends on the type of pizza. {m_pizza->setTopping("ham+pineapple");} }; class SpicyPizzaBuilder : public PizzaBuilder //Concrete Builder 2 { public: virtual void buildDough() //The construction process may vary {m_pizza->setDough("pan baked");} //across different Concrete Builders. virtual void buildSauce() {m_pizza->setSauce("hot");} virtual void buildTopping() {m_pizza->setTopping("pepperoni+salami");} }; //There could be other Concrete Builders added for other kinds of pizza the Chef //designs later
31
Concordia University Department of Computer Science and Software Engineering Builder pattern: example Joey Paquet, 2007-2014 31COMP 345 - Advanced Program Design with C++ class Cook //Director { public: void setPizzaBuilder(PizzaBuilder* pb) //Use a concrete builder { //for building a specific m_pizzaBuilder = pb; //kind of Pizza. } Pizza* getPizza() //get the constructed Pizza { return m_pizzaBuilder->getPizza(); } void constructPizza() //Creational process to create { //a pizza using the builder. m_pizzaBuilder->createNewPizzaProduct(); m_pizzaBuilder->buildDough(); m_pizzaBuilder->buildSauce(); m_pizzaBuilder->buildTopping(); } private: PizzaBuilder* m_pizzaBuilder; };
32
Concordia University Department of Computer Science and Software Engineering Builder pattern: example Joey Paquet, 2007-2014 32COMP 345 - Advanced Program Design with C++ //Pizza Builder Client int main() { Cook cook;//Create the Director PizzaBuilder* hawaiianPizzaBuilder = //Create the Concrete Builder new HawaiianPizzaBuilder; PizzaBuilder* spicyPizzaBuilder = new SpicyPizzaBuilder; cook.setPizzaBuilder(hawaiianPizzaBuilder); //Tell the Director which Builder to use cook.constructPizza(); //Tell the Director to construct the Product Pizza* hawaiian = cook.getPizza(); //Client gets the Product hawaiian->open(); //Client uses the Product cook.setPizzaBuilder(spicyPizzaBuilder); //same for another kind of product cook.constructPizza(); Pizza* spicy = cook.getPizza(); spicy->open(); delete hawaiianPizzaBuilder; delete spicyPizzaBuilder; delete hawaiian; delete spicy; }
33
Concordia University Department of Computer Science and Software Engineering Use the Builder pattern when: The algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled. The construction process must allow different representations for the object that is constructed. Complex objects need to be created that have a common overall structure and interface, even though their internal behavior and detailed structure may be different. Builder pattern: context Joey Paquet, 2007-2014 33COMP 345 - Advanced Program Design with C++
34
Concordia University Department of Computer Science and Software Engineering A Builder lets you vary the internal representation of the product it builds. It also hides the details of how the product is assembled. It provides construction abstraction. Each specific builder is independent of the others and of the rest of the program. This improves modularity and makes the addition of other builders relatively simple. Because each builder constructs the final product step-by- step, you have more control over each final product that a Builder constructs. A Builder pattern is somewhat like an Abstract Factory pattern in that both return classes made up of a number of methods and objects. The main difference is that while the Abstract Factory returns a family of related classes, the Builder constructs a complex object step by step depending on the data presented to it. Builder pattern: consequences Joey Paquet, 2007-2014 34COMP 345 - Advanced Program Design with C++
35
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style Singleton pattern Joey Paquet, 2007-2014 35COMP 345 - Advanced Program Design with C++
36
Concordia University Department of Computer Science and Software Engineering Sometimes it is appropriate to have exactly one instance of a class: window managers, print spoolers, filesystems. Typically, those types of objects known as singletons, are accessed by disparate objects throughout a software system, and therefore require a global point of access. The Singleton pattern addresses all the concerns above. With the Singleton design pattern you can: Ensure that only one instance of a class is created. Provide a global point of access to the object. Allow multiple instances in the future without affecting a singleton class' clients. Singleton pattern Joey Paquet, 2007-2014 36COMP 345 - Advanced Program Design with C++
37
Concordia University Department of Computer Science and Software Engineering The Singleton pattern ensures a class has only one instance, and provides a global point of access to it. The class itself is responsible for keeping track of its sole instance. The class can ensure that no other instance can be created (by intercepting requests to create new objects), and it can provide a way to access the instance. Singletons maintain a static reference to the sole singleton instance and return a reference to that instance from a static instance() method. Singleton pattern Joey Paquet, 2007-2014 37COMP 345 - Advanced Program Design with C++
38
Concordia University Department of Computer Science and Software Engineering Singleton: example Joey Paquet, 2007-2014 38COMP 345 - Advanced Program Design with C++ class Singleton { private: static Singleton *SingletonObject; //private static instance protected: Singleton(){ //protected constructor: cout<<"My Singleton Object Created\n"; //cannot be called except by } //potential subclass Singleton(const Singleton&); //same thing for copy constructor Singleton& operator= (const Singleton&); //and assignment operator public: static Singleton* getSingletonObject() (){ //public static method used to if(!SingletonObject){ //create instance if does not exist yet SingletonObject = new Singleton; //or return it is it exists } return SingletonObject; } }; Singleton* Singleton::SingletonObject=NULL; //initialize instance to NULL
39
Concordia University Department of Computer Science and Software Engineering The Singleton class employs a technique known as lazy instantiation to create the singleton; as a result, the singleton instance is not created until the Instance() method is called for the first time. This technique ensures that the singleton instance iscreated only when needed. The Singleton class implements a protected constructor so clients cannot instantiate Singleton instances. Protected constructors allow Singleton subclasses to be created. Even though the Singleton is an interesting pattern, it is essentially a global variable, and as such should be used with caution. Singleton Joey Paquet, 2007-2014 39COMP 345 - Advanced Program Design with C++
40
Concordia University Department of Computer Science and Software Engineering Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King, and Shlomo Angel. A Pattern Language. Oxford University Press, New York, 1977. Alexander, Christopher. The Timeless Way of Building. Oxford University Press, 1977. ISBN 978-0-19-502402-9. Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Design Patterns – Elements of Reusable Object-Oriented Software, Adisson- Wesley, 1995. References Joey Paquet, 2007-2014 40COMP 345 - Advanced Program Design with C++
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.