Code Smell

Jul 4, 2013 at 19:00

There is a type of code smell I’ve noticed in C++ code recently, but I would imagine it extends to other languages as well. Consider this class:

class Widget
{
public:
    const std::string Name() const;
    const SomeComplexObject SomeMethod() const;
};

Now consider this class

class Gadget
{
public:
    void ShowName(const Widget & widget) const { std::cout << widget.Name(); }
};

What is the ‘code smell’? It’s a contrived example but remember that your function’s arguments are its interface, and in this case it is ‘wide’. A good rule of thumb with interfaces is to make them as narrow as possible. In other words, the YAGNI principle.

A narrower interface than accepting a Widget is to take a std::string. For complex classes such as:

class Widget
{
public:
  const std::string Name() const;
private:
    Gizmo m_gizmo;
    Bell m_bell;
    Whistle m_whistle;
};

passing around the Widget into Gadget::ShowName can be, and usually is, costly, i.e. compilation times may increase because you are including the headers of Gizmo, Bell, and Whistle, and whatever they include.

Quite often, passing Widget as the argument can be the correct thing to do, because it is strongly typed, and Widget itself may have validated the std::string and guarantees that Widget::Name() returns a string of a certain format.