I don't seem to have write permissions to the entries directory. Here's the structured summary for this source document:

---

GoF Case Study: Decorator, Abstract Factory, and Bridge Patterns in Document Editor Design

This section from the GoF *Design Patterns* case study (Lexi document editor, Sections 2.4–2.6) addresses three design problems — embellishing the user interface, supporting multiple look-and-feel standards, and supporting multiple window systems — each solved by a different pattern. The Decorator pattern wraps glyphs with transparent embellishments (borders, scrollbars). The Abstract Factory pattern creates families of platform-specific widgets without hard-coding concrete classes. The Bridge pattern decouples a Window abstraction from its platform-specific implementation (WindowImp).

Key Concepts

Commands and Syntax


// MonoGlyph forwarding (transparent delegation)
void MonoGlyph::Draw(Window* w) {
    _component->Draw(w);
}

// Border extending parent behavior
void Border::Draw(Window* w) {
    MonoGlyph::Draw(w);   // let component draw first
    DrawBorder(w);         // then draw the border
}

// Abstract Factory: creating widgets without naming concrete classes
ScrollBar* sb = guiFactory->CreateScrollBar();
// instead of: ScrollBar* sb = new MotifScrollBar;

// Factory initialization via environment variable
GUIFactory* guiFactory;
const char* styleName = getenv("LOOK_AND_FEEL");
if (strcmp(styleName, "Motif") == 0) {
    guiFactory = new MotifFactory;
} else if (strcmp(styleName, "Presentation_Manager") == 0) {
    guiFactory = new PMFactory;
} else {
    guiFactory = new DefaultGUIFactory;
}

// Bridge: Window delegates drawing to WindowImp
void Window::DrawRect(Coord x0, Coord y0, Coord x1, Coord y1) {
    _imp->DeviceRect(x0, y0, x1, y1);
}

// WindowImp subclass translates to platform-specific API
void XWindowImp::DeviceRect(Coord x0, Coord y0, Coord x1, Coord y1) {
    int x = round(min(x0, x1));
    int y = round(min(y0, y1));
    int w = round(abs(x0 - x1));
    int h = round(abs(y0 - y1));
    XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);
}

// WindowSystemFactory for creating platform-specific implementations
class WindowSystemFactory {
public:
    virtual WindowImp* CreateWindowImp() = 0;
    virtual ColorImp* CreateColorImp() = 0;
    virtual FontImp* CreateFontImp() = 0;
};

// Window constructor uses factory to get correct implementation
Window::Window() {
    _imp = windowSystemFactory->CreateWindowImp();
}

Relationships

Exam-Relevant Points