template design pattern

#include <iostream>

// Step 1: Define an abstract base class (Template)
template <typename T>
class AbstractTemplate {
public:
    void templateMethod() {
        // Step 4: Call the primitive operations
        primitiveOperation1();
        primitiveOperation2();
    }

    virtual ~AbstractTemplate() = default;

private:
    // Step 2: Declare primitive operations as pure virtual functions
    virtual void primitiveOperation1() = 0;
    virtual void primitiveOperation2() = 0;
};

// Step 3: Create concrete implementations of the template
class ConcreteTemplateA : public AbstractTemplate<int> {
private:
    // Step 5: Implement primitive operations for ConcreteTemplateA
    void primitiveOperation1() override {
        std::cout << "ConcreteTemplateA: Primitive Operation 1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteTemplateA: Primitive Operation 2" << std::endl;
    }
};

class ConcreteTemplateB : public AbstractTemplate<double> {
private:
    // Step 5: Implement primitive operations for ConcreteTemplateB
    void primitiveOperation1() override {
        std::cout << "ConcreteTemplateB: Primitive Operation 1" << std::endl;
    }

    void primitiveOperation2() override {
        std::cout << "ConcreteTemplateB: Primitive Operation 2" << std::endl;
    }
};

// Step 6: Client code
int main() {
    ConcreteTemplateA concreteA;
    ConcreteTemplateB concreteB;

    concreteA.templateMethod();
    concreteB.templateMethod();

    return 0;
}