State, Strategy, and Template Method Patterns (GoF Behavioral Patterns)

This section covers implementation details and sample code for the State pattern (continued), the complete Strategy pattern, and the beginning of the Template Method pattern. All three are behavioral patterns from the Gang of Four catalog that deal with varying behavior—State through internal object state, Strategy through interchangeable algorithms, and Template Method through subclass-defined steps in a fixed algorithm skeleton.

Key Concepts

State Pattern (continued):

Strategy Pattern:

Template Method Pattern:

Commands and Syntax

State pattern — TCP Connection example (C++):


// Context class delegates to State
class TCPConnection {
    void ActiveOpen()  { _state->ActiveOpen(this); }
    void Close()       { _state->Close(this); }
    // ... all requests forwarded to _state
    TCPState* _state;
};

// State base class — default (no-op) implementations
class TCPState {
    virtual void ActiveOpen(TCPConnection*) { }
    virtual void Close(TCPConnection*) { }
protected:
    void ChangeState(TCPConnection* t, TCPState* s) {
        t->ChangeState(s);
    }
};

// Concrete states implement transitions
void TCPClosed::ActiveOpen(TCPConnection* t) {
    ChangeState(t, TCPEstablished::Instance());
}
void TCPEstablished::Close(TCPConnection* t) {
    ChangeState(t, TCPListen::Instance());
}

Strategy pattern — Composition/Compositor example (C++):


// Strategy interface — "take the data to the strategy" approach
class Compositor {
    virtual int Compose(
        Coord natural[], Coord stretch[], Coord shrink[],
        int componentCount, int lineWidth, int breaks[]
    ) = 0;
};

// Context delegates to Strategy
void Composition::Repair() {
    breakCount = _compositor->Compose(
        natural, stretchability, shrinkability,
        componentCount, _lineWidth, breaks
    );
}

// Client selects strategy at construction
Composition* quick = new Composition(new SimpleCompositor);
Composition* slick = new Composition(new TeXCompositor);
Composition* iconic = new Composition(new ArrayCompositor(100));

Strategy as template parameter (C++):


template <class AStrategy>
class Context {
    void Operation() { theStrategy.DoAlgorithm(); }
    AStrategy theStrategy;
};
Context<MyStrategy> aContext;  // compile-time binding

Template Method — OpenDocument example (C++):


void Application::OpenDocument(const char* name) {
    if (!CanOpenDocument(name)) return;      // hook: subclass override
    Document* doc = DoCreateDocument();       // factory method step
    if (doc) {
        _docs->AddDocument(doc);
        AboutToOpenDocument(doc);             // hook: notification
        doc->Open();
        doc->DoRead();                        // abstract: subclass must implement
    }
}

Relationships

Exam-Relevant Points