Lecture 20

Recall turtle and weapon example in last lecture.

Visitor Pattern Ctd.

  • visitor can be used to add functionality to existing classes, without changing or recompiling the classes themselves eg. Add a visitor to the Book hierarchy

// Compare this example to the turtle/weapon example
class Book { // Enemy
  public:
    virtual void accept (BookVisitor &v) { // beStruckBy
      v.visit(*this);
    }
};

class Text: public Book {
  public:
    void accept (BookVisitor &v) {
      v.visit(*this);
    }
};

class BookVisitor { // Weapon
  public:
    virtual void visit(Book &b) = 0; // strike
    virtual void visit(Text &t) = 0;
    virtual void visit(Comic &c) = 0;
};

Application: Track how many of each type of Book I have

  • Books: by author

  • Texts: by topic

  • Comics: by hero

How to collect this information?

  • Use a map<string, int>

    • Could write a virtual updateMap method

  • OR write a visitor:

  • Won't compile - there is a cycle of includes

  • Book and BookVisitor include each other

    • whichever is first won't know about the second

Compilation Dependencies

  • When does a file need to #include another file?

Consider: Which of the following classes need to #include "a.h"

The Point: If the code doesn't need an #include, don't create a needless compilation dependency by including unnecessarily.

When A changes, only A,B,C,F need recompilation In the implementations of D,E:

Do the include in the .cc file instead of the .h file (where possible)

Now consider the XWindow class:

**What if I need to add or change a private member? All clients must recompile, would be better to hide these details away.

Solution:

Bridge Pattern

Pimpl Idiom (Pointer to Implementation)

Create a second class XWindowImpl:

  • No need to include Xlib.h

  • Forward declare the impl class

  • No compilation dependency on XWindowImpl.h

  • Clients also don't depend on XImpl.h

  • Other methods

    • replace fields d, w, s, gc, colours with pImpl->d, pImpl->w, etc.

Changing private fields => only recompile Window.cc and relink

Generalization: What if there are several possible window implementations, say XWindow and YWindow

  • then make Impl struct a superclass

UML

  • pImpl idiom and hierarchy or implementation is called the Bridge Pattern

Last updated

Was this helpful?