0

I have a class that does something similar to:

class B{
    void x(){
        statement-block1;
        statement-block2;
        statement-block3;
        statement-block4;
    }

    void y(){
        statement-block5;
        statement-block6;
        statement-block7;
        statement-block8;
    }
}

I need to add a new class that does this:

class C{
    void x(){
        statement-block1;
        statement-block200;
        statement-block3;
        statement-block4;
    }

    void y(){
        statement-block5;
        statement-block6;
        statement-block700;
        statement-block8;
    }
}

I was considering combining the reusable logic this way:

class A{
    void x(){
        statement-block1;
        statement-block2;
        u();
        statement-block4;
    }

    void y(){
        statement-block5;
        statement-block6;
        v();
        statement-block8;
    }

    virtual void u(){
        default-message;
    }

    virtual void v(){
        default-message;
    }
}

class B : A{
    void u(){
        statement-block3;
    }

    void v(){
        statement-block7;
    }
}

class C : A{
    void u(){
        statement-block200;
    }

    void v(){
        statement-block700;
    }
}

Is there a better way to implement this, a different/better way of injecting sub-class-specific code, or is there a design pattern I can use? In the future, I might have to add more classes similar to B and C.

Thanks!

4
  • if all the statement-block is short/simple (like declare variable), I would consider not change the code at all. or if it's not, maybe you have too long function body? Commented Feb 22, 2018 at 2:24
  • if you provide more context, I think it's easier to get answer close to your real problem. Commented Feb 22, 2018 at 2:27
  • The amount of common/reusable part of the code would be around 90% of the implementation. The sub-class specific code would be smaller. ie x or y would have 90% of the lines and u or v would be just 10%. I am leaning towards passing in a function pointer or a lambda now. But there would be more function-pairs with the same 90%-10% pattern. What i was more worried about was about the scalability. Would this be refactorable if, later, there is a new class whose u and v and bigger. Commented Feb 22, 2018 at 3:10
  • 1
    depend on your context, you may want to use CRTP Commented Feb 22, 2018 at 3:12

2 Answers 2

1

It depends what you are trying to achieve. If the statements block are likely to change in run time (dynamic) then use virtual pointer as you showed in your example, however if those are not dynamic, then pass a template parameter instead, in that way you don't pay for what you don't use (virtual pointer). i.e.

class B
{
  public:
    template <typename T>
    void x(T f)
    {
      f();
    }
};

void g(){ std::cout << "value" << std::endl;}

int main()
{
  B b {};
  b.x(g);
}
Sign up to request clarification or add additional context in comments.

Comments

1

Your approach looks great. It applied KISS which is most often the best design pattern to use! You could do this

virtual void u(){
    default-message;
}

virtual void v(){
    u();
}

But that's up to you I guess

Another option is to combine all classes and use std function or a function pointer for that function call that changes.

1 Comment

One more option is to rely on the so-called static polymorphism and hide those block2 and block200 in a template parameter (a policy or whatever).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.