Search code examples
c++refactoringcoding-styleboilerplate

Avoiding boilerplate code in a one-to-one association relationship


Although I'm programming in C++, this is more of a general question about design.

I noticed that when I have objects in a one-to-one association relationship, there tend to be a lot of common methods between them, leading to boilerplate code that essentially directly calls methods of the inner class.

As an example, I have a class called Tab that represents a tab and it's corresponding widget. I also have a class called Tabbable that objects can inherit, so they can be displayed in tabs. A Tab can then take this Tabbable object and render itself correctly. Both these classes have a lot of similar methods relating to the title or icon for example.

class ITabbable {
    public:
    ITabbable();
    virtual ~ITabbable();

    virtual string getTitle() = 0;
    virtual widget getContentWidget() = 0;


    // etc...
}


class Tab {
    public:
    Tab(ITabbable* tabbableObject);


    // lots of boilerplate code:
    string getTitle() {
        return m_tabbableObject->getTitle();
    }

    widget getContentWidget() {
        return m_tabbableObject->getContentWidget();
    }

    // etc...

    private:
    ITabbable* m_tabbableObject; // association relationship
}

A lot of code is duplicated and seems unnecessary. Inheritance definitely doesn't work here because you can't put a Tab in Tab.

Is this just something we have to deal with? Or are there ways around these situations?


Solution

  • Well. To this particular situation. Why not simply implement Tab::getTabbable()?

    Like this:

    const ITabbable* Tab::getTabbable() const { return m_tabbableObject; }
    

    Then users can do:

    const ITabbable* obj = tab->getTabbable();
    string title = obj->getTitle();
    

    You don't have to replicate all functionality.


    Update: This refactoring is usually called Remove Middle Man.