空的重写方法是接口设计不好的标志吗

Are empty overridden methods a sign of bad interface design?

本文关键字:标志 接口 重写 方法      更新时间:2024-09-29

我想知道从抽象接口类继承的空重写方法是否是糟糕接口设计的标志。有时,接口包含的方法只对所有可能的实现类部分有用;在不需要未使用的方法的类中,它们只是留空。

在下面的示例中,connect()disconnect()对于两个实现类IpConnectionSmtpConnection是公共的。然而,prepare()SmtpConnection中不是必需的,并且是空的。

在这种情况下,是从抽象接口IConnection中删除prepare()并显式调用它更好,还是将其留空?如果空的(未使用的(方法越来越多怎么办?

#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();
}

接口是两个模块之间的一种"契约"类型。通常,接口指定如何允许另一个模块使用实现模块实例的功能。

因此,实际上接口与实现本身没有任何关系。它只是列出了规则,可能是一些诱导流约束和保护条款,任何实施都必须遵守这些规则和条款才能提供功能性实施。

因此,如果接口需要用一个空的主体来覆盖,那就完全可以了。其他实现可能非常需要工作。当然,如果知道这是永远不会发生的,那么最好不要在这一点上过度设计,只需删除接口调用。

在你的情况下,我不会太担心,把它作为一个界面。只有当重写方法非常特定于该实现的流,并且对其他实现不太有用时,直接调用功能才有意义。