継承と組み合わせてオブザーバーパターンを実現するにはどうすればよいですか?

ダニエル

構成ファイルを管理するクラスがありSettingsControllerSettingsClient(1 つの純粋な仮想関数、メンバーなし) を登録できます。SettingsClientそれがリフレッシュすることができるように、関連する設定エントリを変更したときに通知されます。

これで、RepositoryBaseいくつかの構成エントリが必要なため、 で継承SettingsClientして登録するものSettingsControllerと、ConcreteRepositoryいくつかの構成エントリが必要で、クライアントを継承してコントローラーで登録する具体的なリポジトリができました。

ConcreteRepository継承RepositoryBaseとの両方継承SettingsClientコントローラ(Javaの中に登録することができるようにするConcreteRepositoryだろうとの両方でしょう)。extendRepositoryBaseimplementSettingsClient

私の問題は次のとおりです。コンパイラは、あいまいであるため、これを行わないように警告します。悲しいことに、仮想継承はどちらかの実装された機能を上書きし、2 つのクラスのいずれConcreteRepositoryRepositoryBaseの更新機能を無効にするため、ここでは役に立ちません

この継承とオブザーバーの組み合わせを実現する方法はありますか? これは設計上の欠陥でありRepositoryBaseConcreteRepository(?) のメンバーである必要があると考えています。

概要を説明するためのコードを次に示します。

#include <vector>
#include <iostream>

class SettingsClient {
public:
  virtual void reloadSettings() = 0;
};

class SettingsController {
  void notify(){
    for(SettingsClient* client : clients){
      client->reloadSettings(); // error! reloadSettings() of RepositoryBase or ConcreteRepository?
    }
  }
  void registerClient(SettingsClient *client) {
    clients.push_back(client);
  }

  std::vector<SettingsClient*> clients;
};

class RepositoryBase : private SettingsClient {
  // ...
  virtual void reloadSettings() {
    std::cout << "Reloading Base!" << "\n";
  }
  // ...
};

class ConcreteRepository : private SettingsClient, private RepositoryBase {
  // ...
  virtual void reloadSettings() {
    std::cout << "Reloading ConcreteRepository!" << "\n";
  }
  // ...
};
ジョセフ・トムソン

ConcreteRepositoryからも継承する必要はありませんSettingsClientリポジトリを基本クラス コンストラクターに一度登録してreloadSettingsから、サブクラス バージョンから基本クラス呼び出すことができます

class RepositoryBase : private SettingsClient
{
public:
  RepositoryBase(SettingsController& controller)
  {
    controller.registerClient(this);
  }

private:
  void reloadSettings() override
  {
    std::cout << "Reloading RepositoryBase\n";
  }
};

class ConcreteRepository : public RepositoryBase
{
public:
  using RepositoryBase::RepositoryBase;

private:
  void reloadSettings() override
  {
    std::cout << "Reloading ConcreteRepository\n";
  }
};

私たちは、使用民間からの継承をSettingsClient防ぐために、reloadSettingsサブクラスで公開さであることから。基本クラスの関数を呼び出す必要がある場合は、カプセル化が弱くなるという代償を払って、代わりに保護された継承を使用できます

class RepositoryBase : protected SettingsClient
{
public:
  RepositoryBase(SettingsController& controller)
  {
    controller.registerClient(this);
  }

protected:
  void reloadSettings() override
  {
    std::cout << "Reloading RepositoryBase\n";
  }
};

class ConcreteRepository : public RepositoryBase
{
public:
  using RepositoryBase::RepositoryBase;

protected:
  void reloadSettings() override
  {
    RepositoryBase::reloadSettings();
    std::cout << "Reloading ConcreteRepository\n";
  }
};

基底クラスとサブクラスに 2 つの個別のクライアントを登録する必要がある場合、またはそれを希望する場合は、合成を使用できます。

class RepositoryBase
{
public:
  RepositoryBase(SettingsController& controller)
  {
    controller.registerClient(&client);
  }

private:
  struct : public SettingsClient
  {
    void reloadSettings() override
    {
      std::cout << "Reloading RepositoryBase\n";
    }
  } client;
};

class ConcreteRepository : public RepositoryBase
{
public:
  ConcreteRepository(SettingsController& controller) : RepositoryBase(controller)
  {
    controller.registerClient(&client);
  }

private:
  struct : public SettingsClient
  {
    void reloadSettings() override
    {
      std::cout << "Reloading ConcreteRepository\n";
    }
  } client;
};

非静的メンバーにアクセスする必要がある場合は、クライアントにリポジトリへのポインタを与えることができます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Rails(5.0.0.1)でポリモーフィズムと継承を組み合わせるにはどうすればよいですか?

分類Dev

パンダデータフレームで組み合わせの組み合わせを取得するにはどうすればよいですか?

分類Dev

調査データを操作しているときに、パンダの列を組み合わせるにはどうすればよいですか?

分類Dev

シングルトンパターンを依存性注入と組み合わせて使用するにはどうすればよいですか?

分類Dev

複数の同じ機能クラス(コントローラー)を、データオブジェクトをパラメーターとして受け取る1つに組み合わせるにはどうすればよいですか?

分類Dev

Pythonでbase32をhotp(ワンタイムパスワード)と組み合わせて使用するにはどうすればよいですか?

分類Dev

LUAでパターンマッチングを行うときに、単語と数字を組み合わせるにはどうすればよいですか?

分類Dev

パターンとグラデーションを1つのパスに組み合わせるにはどうすればよいですか?

分類Dev

これらの2つの正規表現パターンを組み合わせるにはどうすればよいですか?

分類Dev

2つのテンソルを組み合わせてオーバーラップするにはどうすればよいですか?

分類Dev

PLPGSQLでWITHをFORループと組み合わせて使用するにはどうすればよいですか?

分類Dev

ゾーン化されていない日付とタイムゾーンを「組み合わせる」にはどうすればよいですか?

分類Dev

Laravelと複数のテーブルを組み合わせるにはどうすればよいですか?

分類Dev

フィルタとマスクを組み合わせてSVGを使用してプログレッシブブラーを実現するにはどうすればよいですか?

分類Dev

MavenでWARパッケージとOSGiバンドル作成を組み合わせるにはどうすればよいですか?

分類Dev

CPUとGPUグラフィックを組み合わせてパフォーマンスを向上させるにはどうすればよいですか?

分類Dev

テンプレートと組み合わせてバイナリ算術演算子を使用するにはどうすればよいですか?

分類Dev

列の組み合わせを表示メンバーとして表示するにはどうすればよいですか?

分類Dev

現在利用可能なすべてのコンポーズキーの組み合わせを一覧表示するにはどうすればよいですか?

分類Dev

コマンドパターンをJavaFXGUIと組み合わせるにはどうすればよいですか?

分類Dev

matplotlibボタンをアニメーション機能と組み合わせて使用するにはどうすればよいですか?

分類Dev

flavorDimensionsを使用してフレーバーの組み合わせごとに異なるapplicationIdを設定するにはどうすればよいですか?

分類Dev

トレーニングセット固有の学習パラメータをsklearnオンライン(アウトオブコア)学習と組み合わせるにはどうすればよいですか?

分類Dev

非型テンプレートパラメーターと型テンプレートパラメーターを組み合わせて関数をテンプレート化するにはどうすればよいですか?

分類Dev

このオブジェクトのキー/値のすべての組み合わせをJavaScriptで作成するにはどうすればよいですか?

分類Dev

ボタンとして組み合わせて機能するImageViewに重複するTextViewを実装するにはどうすればよいですか?

分類Dev

ブール比較と「iflet」ステートメントをきれいに組み合わせるにはどうすればよいですか?

分類Dev

パンダ:同じ列値を持つ複数の行を組み合わせて、すべての可能性をカバーする新しいデータフレームを作成するにはどうすればよいですか?

分類Dev

Rの特定のパラメーターに基づいて行を組み合わせるにはどうすればよいですか?

Related 関連記事

  1. 1

    Rails(5.0.0.1)でポリモーフィズムと継承を組み合わせるにはどうすればよいですか?

  2. 2

    パンダデータフレームで組み合わせの組み合わせを取得するにはどうすればよいですか?

  3. 3

    調査データを操作しているときに、パンダの列を組み合わせるにはどうすればよいですか?

  4. 4

    シングルトンパターンを依存性注入と組み合わせて使用するにはどうすればよいですか?

  5. 5

    複数の同じ機能クラス(コントローラー)を、データオブジェクトをパラメーターとして受け取る1つに組み合わせるにはどうすればよいですか?

  6. 6

    Pythonでbase32をhotp(ワンタイムパスワード)と組み合わせて使用するにはどうすればよいですか?

  7. 7

    LUAでパターンマッチングを行うときに、単語と数字を組み合わせるにはどうすればよいですか?

  8. 8

    パターンとグラデーションを1つのパスに組み合わせるにはどうすればよいですか?

  9. 9

    これらの2つの正規表現パターンを組み合わせるにはどうすればよいですか?

  10. 10

    2つのテンソルを組み合わせてオーバーラップするにはどうすればよいですか?

  11. 11

    PLPGSQLでWITHをFORループと組み合わせて使用するにはどうすればよいですか?

  12. 12

    ゾーン化されていない日付とタイムゾーンを「組み合わせる」にはどうすればよいですか?

  13. 13

    Laravelと複数のテーブルを組み合わせるにはどうすればよいですか?

  14. 14

    フィルタとマスクを組み合わせてSVGを使用してプログレッシブブラーを実現するにはどうすればよいですか?

  15. 15

    MavenでWARパッケージとOSGiバンドル作成を組み合わせるにはどうすればよいですか?

  16. 16

    CPUとGPUグラフィックを組み合わせてパフォーマンスを向上させるにはどうすればよいですか?

  17. 17

    テンプレートと組み合わせてバイナリ算術演算子を使用するにはどうすればよいですか?

  18. 18

    列の組み合わせを表示メンバーとして表示するにはどうすればよいですか?

  19. 19

    現在利用可能なすべてのコンポーズキーの組み合わせを一覧表示するにはどうすればよいですか?

  20. 20

    コマンドパターンをJavaFXGUIと組み合わせるにはどうすればよいですか?

  21. 21

    matplotlibボタンをアニメーション機能と組み合わせて使用するにはどうすればよいですか?

  22. 22

    flavorDimensionsを使用してフレーバーの組み合わせごとに異なるapplicationIdを設定するにはどうすればよいですか?

  23. 23

    トレーニングセット固有の学習パラメータをsklearnオンライン(アウトオブコア)学習と組み合わせるにはどうすればよいですか?

  24. 24

    非型テンプレートパラメーターと型テンプレートパラメーターを組み合わせて関数をテンプレート化するにはどうすればよいですか?

  25. 25

    このオブジェクトのキー/値のすべての組み合わせをJavaScriptで作成するにはどうすればよいですか?

  26. 26

    ボタンとして組み合わせて機能するImageViewに重複するTextViewを実装するにはどうすればよいですか?

  27. 27

    ブール比較と「iflet」ステートメントをきれいに組み合わせるにはどうすればよいですか?

  28. 28

    パンダ:同じ列値を持つ複数の行を組み合わせて、すべての可能性をカバーする新しいデータフレームを作成するにはどうすればよいですか?

  29. 29

    Rの特定のパラメーターに基づいて行を組み合わせるにはどうすればよいですか?

ホットタグ

アーカイブ