1 / 54

Lecture 15

Lecture 15. (review of) Design Patterns. Homework 4 Formal Reasoning. Question 1-1: Function: binary relation Declare variables: [NAME] NUMBER == N or NUMBER::= 1698|1573| Question 1-4: define a rank function, then use override symbol. A Roadmap for Today.

Download Presentation

Lecture 15

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 15 (review of) Design Patterns

  2. Homework 4 Formal Reasoning Question 1-1: • Function: binary relation • Declare variables: • [NAME] • NUMBER == N or NUMBER::= 1698|1573| Question 1-4: define a rank function, then use override symbol

  3. A Roadmap for Today This lecture is not about knowing a list of design patterns, but shares my insights of learning and using design patterns. • Design pattern: a big picture • Design patterns (example, general template, analysis) – how to learn design patterns yourself Who should care about this class? If you 1) are simply interested, 2) have an interview soon or 3) you plan to do a lot of OO programming …. • Homework Z • Oluyinka: evolutionary patterns of design and design patterns

  4. Design Patterns - Intro • What are design patterns? • Solution templates – architectural level strategies to organize classes and objects • Name, problem, solution, analysis • Language assumptions: OO (small talk, C++) • Many of the patterns related to GUI design • Goals of the design patterns? • Help OO design: decomposing the system into objects to exploit encapsulation, extensibilityand ease of modification, performance, reusability

  5. Group Design Patterns • Application domain: creational (new class and objects), structural (inheritance) , behavioral (architecture for algorithms) • Scope: class/object patterns • Used together: Composite used with Visitor • Alternatives: Prototype and Abstract Factory

  6. Design Pattern Space Creational Structural Behavioural Class Interpreter Template method Factory Method Adaptor (Class) Abstract Factory Builder Prototype Singleton Adaptor (Object) Bridge Composite Decorator Flyweight Façade Proxy Chain of Responsibility Command Iterator Mediator Memento Observer State Strategy Visitor Scope Object Commonly Used Ones? When did we use them?

  7. Creational patterns • Patterns create class/objects • Certain constraints required by the problems • Class relations • Object relations • Number of instance for a class • Factory, Builder: general – concrete • Abstract Factory, Prototype: whole – parts • Singleton: how to create a class to enforce 1 instance

  8. Factory Method • Interface and subclasses to instantiate interface • A way to build class hierarchy

  9. Factory method docs Application 1 * CreateDoc() NewDoc() OpenDoc() Document Open() Close() Save() MyApplication CreateDoc() MyDocument Document* doc=CreateDoc(); docs.Add(doc); docOpen(); Factory Method

  10. Creator Product FactoryMethod() SomeOperation() product=Factory method ConcreteCreator FactoryMethod() ConcreteProduct Return new ConcreteProduct Factory Method

  11. Factory Method: Participants and Communication • ConcreteProduct (MyDocument): Implements the Product interface. • Product (Document): Defines the interface of objects the factory method creates. • Creator (Application): Declares factory method which returns an object of type Product. Also, may define the factory method to create a Product object. • ConcreteCreator (MyApplication): Overrides the factory method to return an instance of a ConcreteProduct.

  12. Abstract Factory • Interface for creating families of related or dependent objects without specifying concrete classes

  13. Abstract Factory: The Problem 1. Consider a user interface toolkit to support multiple look-and-feel standards. 2. For portability an application must not hard code its widgets for one look and feel. How to design the application so that incorporating new look and feel requirements will be easy?

  14. Client WidgetFactory Window CreateScrollbar() WWindow CreateWindow() MacWindow ScrollBar WWidgetFactory MacScrollBar WScrollBar MacWidgetFactory One for each standard. Abstract Factory: Solution

  15. Abstract Factory: Analysis 1. Define an abstract WidgetFactory class. 2. This class declares an interface to create different kinds of widgets. 3. There is one abstract class for each kind of widget and concrete subclasses implement widgets for different standards. 4. WidgetFactory offers an operation to return a new widget object for each abstract widget class. Clients call these operations to obtain instances of widgets without being aware of the concrete classes they use.

  16. AbstractFactory ConcreteFactory2 Client ProductA1 ProductA2 AbstractProductA AbstractProductB CreateProductA () CreateProductA() CreateProductB() CreateProductB() ConcreteFactory1 ProductB2 ProductB1 Abstract Factory: Structure

  17. Abstract Factory : Participants and Communication • ConcreteFactory: Implements the operations to create concrete product objects. • AbstractFactory: Declares the interface for operations to create abstract product objects • AbstractProduct: Declares an interface for a type of product object. • ConcreteProduct: Defines a product object to be created by the corresponding factory. • Client: Uses only the interface declared by the abstractFactory and AbstractProduct classes.

  18. virtual Maze* MakeMaze() const • { return new Maze;} • virtual Wall* MakeWall() const • virtual Wall* MakeRoom(int n) const • { return new Wall;} • { return new Room;} Abstract Factory: Sample Code // Creates components of mazes. // Builds rooms, walls, and doors. class MazeFactory { • public: • MazeFactory(); // This factory is a collection of // factory methods. Also, this class // acts both as Abstract and Concrete // Factory // more methods. }

  19. Abstract Factory: Sample Code Maze* MazeGame:: CreateMaze (MazeFactory& factory) // Builds a maze. • Maze* aMaze = factory.MakeMaze(); • Room* myroom = factory.MakeRoom(1); • Room* herroom = factory.MakeRoom(2); • Door* aDoor = factory.MakeDoor(myRoom,herRoom) • aMaze AddRoom(myRoom) // One can also create a // BombedMazeFactory with // different types of Rooms // and Walls. • aMaze AddRoom(herRoom) // More code to add walls. }

  20. Singleton • One may use a global variable to access an object but it does not prevent one from creating more than one instance. • Used to ensure that a class has only one instance. For example, one printer spooler object, one file system, one window manager, etc. • Instead the class itself is made responsible for keeping track of its instance. It can thus ensure that no more than one instance is created. This is the singleton pattern.

  21. static Instance() SingletonOp() static uniqueInstance GetSingletonData() singletonData return uniqueinstance Singleton Singleton

  22. public: • static Singleton* Instance(); • protected: • private: • Singleton(); • Static Singleton* _instance // Creation hidden inside Instance(). // Cannot access directly. Singleton Code class Singleton { // Only one instance can ever be created. }

  23. Singleton Code Singleton* Singleton::_instance=0; Singleton* Singleton:: Instance(){ if (_instance ==0) { _instance=new Singleton; } Return _instance; } // Clients access the singleton // exclusively via the Instance member // function.

  24. Create Class/Objects using Creational patterns • Start with simple ones, e.g. factory • Familiar with other patterns so we can perform refactoring during or after implementation • Remember classical problems solved by the correspondent patterns

  25. Structural Patterns • Composition of class and objects: scenarios of inheritances Relationships between parent and child classes: • Adaptor: make two independent classes work together • Bridge: abstract – implementation (window example) • Composite: part-whole tree structure • Decorator: additional responsibility • Façade: provide single interface • Flyweight: a shared object used in different contexts (characters) • Proxy: indirect access to the key functionality

  26. Client Classes Need to communicate with Subsystem classes Facade Pattern: Problem

  27. Client Classes Subsystem classes FacadePattern: Solution Facade

  28. Facade Pattern: Why and What? • Need to provide a simple interface to many, often small, classes. But not necessarily to ALL classes of the subsystem. • Subsystems often get complex as they evolve. • Façade provides a simple default view good enough for most clients. • Facade decouples a subsystem from its clients. • A façade can be a single entry point to each subsystem level. This allows layering.

  29. Facade Pattern: Participants and Communication • Clients communicate with subsystem classes by sending requests to façade. • Participants: Façade and subsystem classes • Façade forwards requests to the appropriate subsystem classes. • Clients do not have direct access to subsystem classes.

  30. Facade Pattern: Benefits • Promotes weak coupling between subsystem and its clients. • Shields clients from subsystem classes; reduces the number of objects that clients deal with. • Helps in layering the system. Helps eliminate circular dependencies.

  31. Compiler Compile() Invocations Stream Scanner Token BytecodeStream Parser Symbol CodeGenerator PnodeBuilder Pnode RISCCodegenerator StackMachineCodegenerator Example: A compiler StatementNode ExpressionNode

  32. Façade Pattern: Code class Scanner { // Takes a stream of characters and produces a stream of tokens. • public: • Scanner (istream&); • virtual Scanner(); • virtual Token& Scan(); • Private: • istream& _inputStream; • };

  33. Façade Pattern: Code class parser { // Builds a parse tree from tokens using the PNodeBuilder. • public: • Parser (); • virtual ~Parser() • virtual void Parse (Scanner&, PNodeBuilder&); • };

  34. virtual Pnode* NewVariable ( • Char* variableName • ) const; • virtual Pnode* NewAssignment ( • Pnode* variable, Pnode* expression • Private: • ) const; • Pnode* _node; • }; Façade Pattern: Code // Builds a parse tree incrementally. Parse tree // consists of Pnode objects. class Pnodebuilder { • public: • Pnodebuilder (); // Node for a variable. // Node for an assignment. // Similarly...more nodes.

  35. // Manipulate program node. • virtual void GetSourcePosition (int& line, int& index); // Manipulate child node. • virtual void Add (Pnode*); • virtual void Remove (Pnode*); // …. • virtual void traverse (Codegenerator&); // Traverse tree to generate code. • protected: • PNode(); • }; Façade Pattern: Code // An interface to manipulate the program node and its children. class Pnode { • public:

  36. // Manipulate program node. • virtual void Visit (StatementNode*); • virtual void Visit (ExpressionNode*); // …. • Protected: • CodeGenerator (BytecodeStream&); • BytecodeStream& _output; • }; Façade Pattern: Code // Generate bytecode. class CodeGenerator { • public:

  37. }; • }; Façade Pattern: Code void ExpressionNode::Traverse (CodeGenerator& cg) { • cg.Visit (this); • ListIterator<Pnode*> i(_children); • For (i.First(); !i.IsDone(); i.Next();{ • i.CurrentItem()Traverse(cg);

  38. Could also take a CodeGenerator Parameter for increased generality. • Compiler(); • virtual void Compile (istream&, BytecodeStream&); } • void Compiler:: Compile (istream& input, BytecodeStream& output) { • Scanner scanner (input); • PnodeBuilder builder; • Parser parser; • parser.Parse (scanner, builder); • RISCCodeGenerator generator (output); • Pnode* parseTree = builder.GetRootNode(); • parseTreeTraverse (generator); Façade Pattern: Code // Façade. Offers a simple interface to compile and // Generate code. class Compiler { • public: }

  39. Behavioral Patterns • Interactions between objects and classes for algorithms: architectural design with the algorithms • Many uses abstract – concrete structure. Object contains: • Iterator/visitor: traversal of aggregate objects (interface reuse and information hiding) – way of access, traverse objects • State: state is the class, behavior (subclass) based on state – state dependent behavior • Strategy: search - algorithm • Mediator: protocol of between objects

  40. Observer Pattern • Need to separate presentational aspects with the data, i.e. separate views and data. • Classes defining application data and presentation can be reused. • Change in one view automatically reflected in other views. Also, change in the application data is reflected in all views. • Defines one-to-many dependency amongst objects so that when one object changes its state, all its dependents are notified.

  41. Relative Percentages A B C D A X 15 35 35 15 D B Y 10 40 30 20 C Z 10 40 30 20 A B C D A=10% B=40% C=30% D=20% Application data Change notification Requests, modifications Observer Pattern

  42. observers Observer Update() Subject For all x in observers{ x  Update(); } attach (Observer) detach (Observer) Notify () Concrete Observer Concrete Subject subject Update() GetState() SetState() observerState subjectState observerState= subject  getState(); Observer Pattern

  43. Abstract class defining the Observer interface. Observer Pattern: Observer code class Subject; • class observer { • public: • virtual ~observer; • virtual void Update (Subject* theChangedSubject)=0; • protected: • observer (); • };

  44. Abstract class defining the Subject interface. Observer Pattern: Subject Code class Subject { • public: • virtual ~Subject; • virtual void Attach (observer*); • virtual void Detach (observer*) ; • virtual void Notify(); • protected: • Subject (); • private: • List <Observer*> *_observers; • };

  45. Observer Pattern: Subject Code void Subject :: Attach (Observer* o){ • _observers -> Append(o); • } • void Subject :: Detach (Observer* o){ • _observers -> Remove(o); • } • void Subject :: Notify (){ • ListIterator<Observer*> iter(_observers); • for ( iter.First(); !iter.IsDone(); iter.Next()) { • iter.CurrentItem() -> Update(this); • } • }

  46. Observer Pattern: A Concrete Subject class ClockTimer : public Subject { public: • ClockTimer(); • virtual int GetHour(); • virtual int GetMinutes(); • virtual int GetSecond(); • void Tick (); • }

  47. Observer Pattern: A Concrete Subject ClockTimer :: Tick { // Update internal time keeping state. // gets called on regular intervals by an internal timer. • Notify(); • }

  48. Override Observer operation. Override Widget operation. Observer Pattern: A Concrete Observer class DigitalClock: public Widget, public Observer { • public: • DigitalClock(ClockTimer*); • virtual ~DigitalClock(); • virtual void Update(Subject*); • virtual void Draw(); • private: • ClockTimer* _subject; • }

  49. Observer Pattern: A Concrete Observer • DigitalClock ::DigitalClock (ClockTimer* s) { • _subject = s; • _subjectAttach(this); • } • DigitalClock ::~DigitalClock() { • _subject->Detach(this); • }

  50. Check if this is the clock’s subject. Observer Pattern: A Concrete Observer • void DigitalClock ::Update (subject* theChangedSubject ) { • If (theChangedSubject == _subject) { • Draw(); • } • } • void DigitalClock ::Draw () { • int hour = _subject->GetHour(); • int minute = _subject->GeMinute(); // etc. • // Code for drawing the digital clock. • }

More Related