2016-05-29 9 views
1

「半仮想」メソッドが存在しないことは知っていますが、デザインに関連する問題が発生しました。「半仮想」メソッドを実装するためのベストプラクティスは何ですか?

私は、WebPageという基本クラスを持っているとしましょう。このクラスにはUpdatePage()というメソッドがあります。しかし、このメソッドは抽象WebPageオブジェクト内に存在するため、UpdatePage()メソッドは仮想であり、WebPageから具体的なクラスを派生しているユーザーが実装する必要があります。

しかし、UpdatePage()メソッドが呼び出されたとき、最後の更新時間に関するクラスデータメンバのタイムスタンプを作成するのが理想的です。

私は、メソッドからのデフォルトの実装(タイムスタンプを行う)が必要な位置にありますが、実装は基本クラスのWebPageから派生した具体的なクラスのカスタムにしたいと思っています。

私はこの問題を解決するための技術を考え出すことができます。たとえば、私はUpdatePage()を非仮想にして、非仮想のtimeStamp()メソッドと純粋仮想のupdateImplementation()メソッドの2つのメソッドを含むことができます。このようにして、ユーザーがUpdatePage()を呼び出すと、デフォルトおよびカスタム動作が存在します。

もう一度、このためにデザインパターン/ルールが存在する場合、私はホイールを再発明したくありません。

ありがとうございます!

+3

メイクは '公共および非仮想UpdatePage'、そしてそれは、別のメソッドを呼び出す' DoUpdatePage'は、それが保護され、仮想だと言うします。派生クラスは後者を実装します。前者は、前後に必要な共通タスクを実行できます。 –

+2

[テンプレートメソッドパターン](https://en.wikipedia.org/wiki/Template_method_pattern)を探していますか? – PaulMcKenzie

+1

仮想関数を呼び出し、他の操作を実行する非仮想パブリック関数について言及すると、あなたは[NVI idiom](http://www.gotw.ca/publications/mill18.htm)について議論しているようです仮想関数呼び出しの前または後。 –

答えて

3

質問に記載されているのは、問題を解決するのに適したTemplate Methodパターンです。

簡単に

、あなたのUpdatePage()は流れの「テンプレート」を提供するために起こっている、と派生クラスはテンプレートの欠けている部分を提供してみましょう:

class WebPage { 
public: 
    virtual UpdatePage() { // optional for the virtual 
     // Update the timestamp 

     // Call the logic provided by derived class 
     DoUpdatePage(); 

     // Some other logic afterwards if you need 
    }; 

protected: 
    virtual DoUpdatePage() = 0; // you may also provide a default impl too 
}; 

(、正しい構文をウィッシュかなりされています


別の可能なパターンは、あなたのデザインに応じて、デコレーターです)いくつかの時間は、C++を触れていない。しかし、アイデアは、しかし明確にする必要があります。要するに

は、代わりに、直接派生クラスを利用するのは、タイムスタンプロジックを提供

例えばデコレータによってそれを飾ります

class WebPage { 
public: 
    virtual void UpdatePage() = 0; 
}; 

class TimeStampWebPageDecorator : public WebPage { 
public: 
    TimeStampWebPageDecorator(WebPage* webpage) : impl(webpage) { 
    } 

    virtual void UpdatePage() { 
     // logic for the timestamp stuff 

     impl->UpdatePage(); 

     // some other logic after calling impl 
    } 

private: 
    WebPage * impl; 
} 

あなたが呼び出すためのWebPageのimplを持っているのであれば、あなたはTimeStampWebPageDecoratorとそれを飾ることがあります。例えば。

FooWebPage fooWebPage{}; 

// Instead of invoking fooWebPage directly like this. 
// WebPage& webpage = fooWebPage; 
// webpage.UpdatePage() 

// Decorate it first 
WebPage& webpage = TimeStampWebPageDecorator{&fooWebPage}; 
webpage.UpdatePage() 
関連する問題