# 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

![](https://github.com/lauradang/wiki-notes/blob/master/Users/lauradang/Desktop/CS246/UMLs/observerpatternuml.jpg)

**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)

```
// Subject Class
class Subject {
  vector<Observer*> observers;
  
  public:
    void attach(Observer *ob) {
      observers.emplace_back(ob);
    }
    
    void detach(Observer *ab); // remove from observers (must loop through)
    
    void notifyObservers() {
      for (auto &ob:observers) {
        ob->notify();
      }
    }
    
    virtual ~Subject();    
};

Subject::~Subject() {}

// Observer class
class Observer {
  public:
    virtual void notify() = 0;
    virtual ~Observer() {}
};

// ConcreteSubject class
class HorseRace: public Subject {
  ifstream in; // source of data
  string lastWinner;
  
  public:
    HorseRace(string source): in{source} {}
    
    bool runRace() {
      return in >> lastWinner;
    }
    
    string getState() {
      return lastWinner;
    }
};

// ConcreteObserver class
class Bettor: public Observer {
  HorseRace *subject;
  string name, myHorse;
  
  public:
    Bettor(Horse Race *subject, string name, string myHorse) {
      subject->attach(this);
    }
    
    ~Bettor() {
      subject->detach(this);
    }
    
    void notify() {
      string winner = subject->getState();
      if (winner == myHorse) {
        cout << "win!" << endl;
      } else {
        cout << "Lose :(" << endl;
      }
    }
}

int main() {
  HorseRace hr;
  Bettor Larry {&hr, "Larry", "OliviaTheFuckFace"};
  while (hr.runRace()) {
    hr.notifyObservers();
  }
}
```

## 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

![](https://github.com/lauradang/wiki-notes/blob/master/Users/lauradang/Desktop/CS246/UMLs/decoratorpatternUML.jpg)

**`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

```
// Basic pizza is crust and sauce

// Component Class (Abstract)
class Pizza {
  public:
    virtual float price() const=0;
    virtual string desc() const=0;
    virtual ~Pizza() {}
};

// Decorator Class (Abstract)
class Decorator: public Pizza {
  protected:
    Pizza *component;
  public:
    Decorator (Pizza *p): component{p} {}
    virtual ~Decorator() {
      delete component;
    }
}

// ConcreteDecorator Class
class CrustAndSauce: public Pizza {
  public:
    float price() const override {
      return 5.99;
    }
    
    string desc() const override {
      return "pizza";
    }
};

class StuffedCrust: public Decorator {
  public:
    stuffedCrust (Pizza *p): Decorator {p} {}
    
    float price() const override {
      return component->price() + 2.69;
    }
    
    string desc() const override {
      return component->desc() + "with stuffed crust";
    }
}

// Other classes are similar to StuffedCrust
```

### UML

![](https://github.com/lauradang/wiki-notes/blob/master/Users/lauradang/Desktop/CS246/UMLs/decoratorpizzaUML.jpg)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lauradang.gitbook.io/notes/c++/cs_246/lecture-18.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
