2012-02-12 7 views
1

私は基本的に次の値を取得しようとするnextと以前の値を返すprevの2つのメソッドを持っています。デコレータまたは抽象基本クラス?どちらも正しく見えません

struct foo 
{ 
    virtual boost::optional<int> next() = 0; 
    virtual int prev() = 0; 
}; 

インタフェースは基本的に第1 nextを呼び出して使用され、それが失敗した場合には、prevと前の値を取得することが可能です。 prevは、この例のように些細なものではなく、prevの値には他のものがあるはずです。 prevメソッドは、すべてのクラスでほぼ同じように機能し、そのデフォルト実装を提供したいと思います。私が好きどちらも、これを実現するための方法、に持って

最初の可能性ではなく、インターフェースの抽象基本クラスです。しかし、それは今、インターフェイスを壊す

struct abstract_foo : public foo 
{ 
    int prev_; 

    virtual boost::optional<int> next() 
    { 
     boost::optional<int> val = do_next(); 
     if(val) 
      prev_ = *val; 
     return val;   
    } 

    int prev() 
    { 
     return prev_; 
    } 

    virtual boost::optional<int> do_next() = 0; 
}; 

1のいずれかabstract_foo::nextを呼び出すことやdo_nextむしろ醜いを実装することを強制すること覚えておく必要があります。

別の方法がデコレータ使用している:ここでは

struct foo 
{ 
    virtual boost::optional<int> next() = 0; 
    virtual int prev() 
    { 
     throw not_implemented(); 
    } 
}; 

struct foo_decorator : public foo 
{ 
    std::unique_ptr<foo> foo_; 
    int prev_; 

    foo_decorator(std::unique_ptr<foo>&& foo) 
     : foo_(std::move(foo)) 
    { 
    } 

    boost::optional<int> next() 
    { 
     boost::optional<int> val = foo_->next_value(); 
     if(val) 
      prev_ = *val; 
     return val; 
    } 

    int prev() 
    { 
     return prev_; 
    } 
}; 

を、not_implementedだけで、ユーザーが基本クラスから直接prevを使用することができると思うの事故のために叫びます。

誰も良いデザインをお勧めしますか?または、派生クラスで手動で実装するのに役立つヘルパークラスをいくつか用意するだけですか? next()prev()は非仮想であり、do_next()がプライベートでどのように

class foo 
{ 
    public: 
    boost::optional<int> next() 
    { 
     boost::optional<int> val = do_next(); 
     if(val) 
      prev_ = val; 
     return val; 
    } 

    int prev() 
    { 
     return prev_; 
    } 

    private: 
    int prev_; 
    virtual boost::optional<int> do_next() = 0; 
}; 

注:

答えて

0

、なぜ、基本クラスで、すでに前を実装していない:

struct foo 
{ 
public: 
    virtual boost::optional<int> next() = 0; 
    int prev() 
    { 
     return prev_; 
    } 
protected: 
    int prev_; 
}; 

struct foo_decorator : public foo 
{ 
    std::unique_ptr<foo> foo_; 

    foo_decorator(std::unique_ptr<foo>&& foo) 
     : foo_(std::move(foo)) 
    { 
    } 

    boost::optional<int> next() 
    { 
     boost::optional<int> val = foo_->next_value(); 
     if(val) 
      prev_ = *val; 
     return val; 
    } 
}; 
関連する問題