TITLE: the capsule design pattern (part II) CLARKE: Allan Clarke (clarke@ses.com) [ This is a continuation of a look at Robert Martin's article "Cross Casting: The Capsule Pattern", in the June 97 issue of "The C++ Report". You can find the first part at http://www.ses.com/~clarke/cpptips/capsule -adc ] A problem in using the capsule pattern so far lies in the client type testing: Capsule* cap = lowerLayers (...); if (dynamic_cast(cap)) { // process the GUI error here } else if (dynamic_cast(cap)) { // process the comm error here } else if (...) { ... } Of course any self respecting OO designer would see red flags and hear sirens going off when encountering code like this; the suggestion of a virtual function should be overpowering. Adding more derived error types requires that this code be changed. To address the brittleness in the above code, observe the following technique: class IGuiErrorHandler { public: virtual void handlA (...) = 0; virtual void handlB (...) = 0; virtual void handlC (...) = 0; }; class GUIError { public: virtual ~GUIError () {} virtual void handle (IGuiErrorHandler&) = 0; }; class ErrorA : public GUIError { ... virtual void handle (IGuiErrorHandler& geh) { geh.handleA (this); } }; class ErrorB : public GUIError { ... virtual void handle (IGuiErrorHandler& geh) { geh.handleB (this); } }; class ErrorC : public GUIError { ... virtual void handle (IGuiErrorHandler& geh) { geh.handleC (this); } }; Finally the client code might be found in a class like this class GUI : public IGuiErrorHandler { public: ... virtual void handleA (...); virtual void handleB (...); virtual void handleC (...); ... }; Nifty, eh?