Search code examples
oopdesign-patternsooad

Template method pattern: changing the algorithm's architecture


I'm using template method pattern in my project like following

class Template
{
public:
void algorithm();
{
    A();
    B();
}
private:
virtual void A()=0;
virtual void B()=0;
}

I have some subclasses implement method A & B in different ways.
But now I need a new class Template2 to implement a slightly different algorithm.

class Template2
{
public:
void algorithm();
{
    A();
    B();
    C();
}
private:
virtual void A()=0;
virtual void B()=0;
void C()
{
    //some stuff
    A();
    //some stuff
    B();
}
}

C is identical along all subclasses, so I do not make it virtual.
Right now I create a new inheritance hierarchy based on Template2, but this seems stupid because I have to copy and paste every subclasses's code in this new hierarchy.
Is there anyway to do it in a more elegant way?

EDIT
Sorry, I did not make my point clear.
Now I have two inheritance hierarchy.
1. An abstract class Template and some subclasses A1,A2,A3,A4...
2. An abstract class Template2 and some subclasses B1,B2,B3,B4...
This works fine, but I'm wondering if there's a way to somehow merge these two hierarchies because A1 and B1 has the same code except they're derived from Template and Template2 respectively.
Whether the solution is template method pattern is irrelevant for me
Both bcperth and Spotted's answers work for me :)
Thanks a lot.


Solution

  • I agree with Spotted, but have you considered just adding additional algorithms to your template class? Its still Template Pattern with multiple algorithms. You get a fatter class but no code repetition. Below is an illustration.

    #include <iostream>
    
    using namespace std;
    
    class Template
    {
    public:
        void algorithm1()
        {
            A();
            B();
        }
    
        void algorithm2()
        {
            A();
            B();
            C();
        }
    
    private: void C()
        {
        cout << endl << "start C() ";
        A();
        cout << "middle C() ";
        B();
        cout << "end C()" << endl;
        }
    
    private:
        virtual void A() = 0;
        virtual void B() = 0;
    };
    
    class real :public Template {
    
        void A() { cout << "A(1)  "; }
        void B() { cout << "B(1) "; }
    };
    
    int main()
    {
        real Real;
        cout << "algorithm1" <<endl;
        Real.algorithm1();
        cout << endl;
        cout << endl << "algorithm2 << endl";
        Real.algorithm2();
    
        return 0;
    }