Lecture 18

Design Patterns Continued

Guiding Principle: Program to the interface, not the implementation

  • Abstract base classes define the interface

    • they work with base class pointers and call their methods

  • Concrete subclasses can be swapped in and out

    • Abstraction over a variety of behaviours

The point: Even if you don't have an abstract base class, you should probably make one anyway

Iterator Pattern

class List {
  ...
  public:
    class Iterator: public AbstractIterator {
      ...
    };
};

class AbstractIterator {
  public:
    virtual int &operator*()=0;
    virtual AbstractIterator &operator++=0;
    virtual bool operator!=(AbstractIterator &other)=0;
    virtual ~AbstractIterator() {};
};

class Set {
  ...
  public:
    class Iterator: public AbstractIterator {
      ...
    }; 
};

// Then you can write code that operators over iterators.

// works over Lists and Sets
void for_each(Abstract Iterator &start, AbstractIterator &finish, int(*f)(int)) {
  while (start != finish) {
    f(*start);
    ++start;
  }
}

Observer Pattern

  • Aka Publish/subscribe model

  • Publisher/Subject generates data

  • Observers/Subscribers receive data and react to it

    • i.e. Observers/Subscribers automatically updates when subject's data changes

General Example:

  • publisher = spreadsheet cells

  • observers = graphs (when spreadsheet cells change, graph reacts)

Note: Can be many different kinds of observer objects - subject should not need to know all the details

UML

UML Note: Subject class is code common to all subjects, Observer class is interface common to all observers

Observer Pattern's Sequence of Method calls

  1. .Subject's state is updated

  2. .Subject::notifyObservers() - calls each observer's notify()

  3. Each observer calls ConcreteSubject::getState() to query the state and reacts accordingly

Observer Pattern Example:

  • Subject - publishes winners

  • Observers = individual bettors (they'll declare victory when their horse wins)

Decorator Pattern

  • Used to enhance an object during runtime

    • i.e. Add functionality/features when program is running

Example: Windowing system

  • start with basic window

  • add scrollbar

  • add menu

UML

Component defines the interface - i.e. operations your objects will provide ConcreteComponent implements the interface. Decorators - all inherit from Decorator, which inherits from Component

Therefore, every decorator IS-A Component and HAS-A component.

Window example explained:

  • WindowWithScrollBar is a kind of window and has a pointer to the underlying plain window

  • WindowWithScrollBar and menu IS a window and HAS a pointer to a WindowWithScrollBar, which has a pointer to a window

  • pointer always points to a less deccorated version of itself

All inherit from WindowInterface, so Window methods can be used polymorphically on all of them.

Decorator Pattern Example with Code: Pizza

UML

Last updated

Was this helpful?