NVI习惯用法应该用于简单的接口类吗?

时间:2010-08-06 19:24:14

标签: c++

我应该使用哪个?

struct IFilterTreeNode
{
    virtual unsigned int GetEasiestProveRank() const = 0;
    virtual unsigned int GetEasiestDisproveRank() const = 0;
    virtual unsigned int GetEasiestProveNumber() const = 0;
    virtual unsigned int GetEasiestDisproveNumber() const = 0;
    virtual std::vector<IFilterTreeNode *> GetChildren() const = 0;
    virtual bool AttemptToProve() = 0;
    virtual bool AttemptToDisprove() = 0;
    virtual ~IFilterTreeNode() {};
};

或:

class IFilterTreeNode
{
    virtual unsigned int GetEasiestProveRankImpl() const = 0;
    virtual unsigned int GetEasiestDisproveRankImpl() const = 0;
    virtual unsigned int GetEasiestProveNumberImpl() const = 0;
    virtual unsigned int GetEasiestDisproveNumberImpl() const = 0;
    virtual std::vector<IFilterTreeNode *> GetChildrenImpl() const = 0;
    virtual bool AttemptToProveImpl() = 0;
    virtual bool AttemptToDisproveImpl() = 0;
public:
    unsigned int GetEasiestProveRank() const
    {
        return GetEasiestProveRankImpl();
    }
    unsigned int GetEasiestDisproveRank() const
    {
        return GetEasiestDisproveRankImpl();
    }
    unsigned int GetEasiestProveNumber() const
    {
        return GetEasiestProveNumberImpl();
    }
    unsigned int GetEasiestDisproveNumber() const
    {
        return GetEasiestDisproveNumberImpl();
    }
    std::vector<IFilterTreeNode *> GetChildren() const
    {
        return GetChildrenImpl();
    }
    bool AttemptToProve()
    {
        return AttemptToProveImpl();
    }
    bool AttemptToDisprove()
    {
        return AttemptToDisproveImpl();
    }
    virtual ~IFilterTreeNode() {};
};

4 个答案:

答案 0 :(得分:2)

我很懒,我们的大部分代码库都使用了第一个选择,所以这就是我要使用的那个。事情开始变得越来越复杂时,我会立即切换到第二个选择。但就像我说的那样,我很懒。 : - )

第二种选择肯定更具前瞻性和灵活性。优秀的程序员使课程易于使用。让它们易于编写是次要的。

答案 1 :(得分:2)

就我而言,{p> Michael Kristofikanswer是正确的。

但我想补充一点:你的界面将适用于从中继承的所有类型。

所以,除非你能证明只关注少数几个类并且你将在你的控制范围内(并且那里没有脆弱的基类问题的风险),那么< b>你应该谨慎,并使用NVI模式。

因为一旦其他人开始从您的界面继承,就不会轻易回头。

答案 2 :(得分:1)

NVI习语的目标是分离界面和实现。根据面向对象的设计实践,这是你想要的。

如果你认为在这种情况下没有真正的理由这样做,我会做前者。 Herb Sutter argues quite the opposite

你也可能会问,“简单有多简单?”简单可以经常变得复杂。也许从前者开始,在你需要后者之前不要把它改为后者。

答案 3 :(得分:0)

在这个简单的案例中,可能不值得这么麻烦。如果方法有任何参数和/或需要可扩展的日志/仪表/参数预/后处理,我会使用NVI。