HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Moving method from derived class to base

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
frommethodmovingderivedclassbase

Problem

I've some classes (Derived1, Derived2, etc.) derived from class Base. All of derived classes have a following methods (reduced sample):

void Derived1::handleTimer(const StatusType &st) {
  if (!st.isOk()) {
    m_timer->WakeUpPeriod(10); // wait for 10 seconds;
    m_timer->SetHandler(boost::bind(Derived1::handleTimer, this, _1));
    return;
  }

  try {
    ... // there is some specific for Derived's code
    m_timer->WakeUpPeriod(10 * 60); // wait for 10 minutes;
    m_timer->SetHandler(boost::bind(Derived1::handleTimer, this, _1));
  }
  catch(...) {
    m_timer->WakeUpPeriod(10); // wait for 10 second;
    m_timer->SetHandler(boost::bind(Derived1::handleTimer, this, _1));
  }
}

void Derived1::start() {
  m_timer->WakeUpPeriod(1); // wait for 1 second;
  m_timer->SetHandler(boost::bind(Derived1::handleTimer, this, _1));
}


I'd like to move these methods to Base. However, my trying looks pretty ugly. Is there more appropriate way?
There is my current solution.

class Base {
public:
  typedef boost::function  HandlerType;
  Base(HandlerType handler) : m_hadler(handler) {}
  void start() {
    m_timer->WakeUpPeriod(1); // wait for 1 second;
    m_timer->SetHandler(m_handler);
  }
protected:
  virtual void doSomeSpecific() = 0;

  void handleTimer(const StatusType &st) {
    if (!st.isOk()) {
      m_timer->WakeUpPeriod(10); // wait for 10 seconds;
      m_timer->SetHandler(m_handler);
      return;
    }

    try {
      doSomeSpecific();
      m_timer->WakeUpPeriod(10 * 60); // wait for 10 minutes;
      m_timer->SetHandler(m_handler);
    }
    catch(...) {
      m_timer->WakeUpPeriod(10); // wait for 10 second;
      m_timer->SetHandler(m_handler);
    }
  }

private:
  HandlerType m_handler;

  ... // other data and function members
};


Now Derived classes

```
void Derived1::doSomeSpecific() { ... }

Derived1::Derived1() : Base(boost::bind(Derived1::handleTimer, this, _1) {}

void Derived1::handleTimer(const StatusType &st) { Base:

Solution

The use of doSomeSpecific inside of handleTimer is remarkably similar to the Template Pattern.

If there is no base implementation of doSomeSpecific you might consider making it private (still virtual so it can be overridden). Unless of course you really want further derived classes to be able to call the doSomeSpecific implementations of their parent classes.

Also, you can consider making handleTimer non-virtual if all derived classes must have the same behavior.

By making doSomeSpecific private, and handleTimer non-virtual, the only point of customization becomes doSomeSpecific, and it becomes an all or nothing point of customization. This can simplify your implementations of your derived classes, because you can trust that they only customize one specific part of your base class.

Context

StackExchange Code Review Q#37294, answer score: 5

Revisions (0)

No revisions yet.