Are empty overridden methods a sign of bad interface design?

Viewed 71

I was wondering if empty overridden methods inherited from an abstract interface class are a sign of bad interface design. Sometimes interfaces contain methods that are useful only partially for all the possible implemention classes; in the classes where unused methods are not necessary, they are just left empty.

In the following example, connect() and disconnect() are common to the two implementation classes IpConnection and SmtpConnection. However, prepare() is not necessary in SmtpConnection and is left empty.

In this kind of situations, is it better to remove prepare() from the abstract interface IConnection and call it explicitly, or leave it empty? What if empty (unused) methods grow more and more?

#include <memory>

class IConnection
{
public:
    virtual void connect() = 0;    /* common */
    virtual void disconnect() = 0; /* common */
    virtual void prepare() = 0;    /* partial */
};

class IpConnection : public IConnection
{
public:
    void connect()    override { /* ... */ }
    void disconnect() override { /* ... */ }
    void prepare()    override { /* ... */ }
};

class SmtpConnection : public IConnection
{
public:
    void connect()    override { /* ... */ }
    void disconnect() override { /* ... */ }
    void prepare()    override { } /* empty */
};

int main()
{
    std::unique_ptr<IConnection> connection;

    connection = std::make_unique<SmtpConnection>();
    connection->connect();
    connection->prepare();
    connection->disconnect();
}
1 Answers

An interface is a type of 'contract' between two modules. Typically, an interface specifies how another module is allowed to make use of the functionality of the implementing module instance.

So in fact the interface has no business with the implementation itself. It just sets out the rules, possibly some induced flow constraints and protection provisions that any implementation must adhere to in order to provide a functional implementation.

So, if the interface needs to be overriden with an empty body, that' is totally fine. Other implementations may very well need to do work. Of course if you know that that is never going to happen, well perhaps is better not to over-design at that point, and just remove the interface call.

In your case I would not worry too much and leave it as an interface. Calling functionality directly makes sense ONLY if the overriding method is quite specific to the flow of that implementation, and less useful for other implementations to worry about.

Related