web-dev-qa-db-ja.com

データをコンストラクターに渡すか、代わりに仮想メソッドを作成しますか?

データベースを記述するオブジェクト指向モジュールで、派生クラスのコンストラクターのコンストラクターにDB記述データ構造を渡すか、代わりにデータ構造を作成してそれらを呼び出す(動的な「仮想」)メソッドを作成する必要があります。コンストラクタ?

これらのデータ構造は長いです(約100要素の配列)。

A Python例は次のとおりです:

class Base:
  def __init__(data_desciption):
    self.data_desciption = data_desciption

vs

class Base:
  def __init__():
    self.data_desciption = self.data_desciption_init()

またはC++の場合:

 class Base {
   DataDescription data;
 public:
   Base(DataDescription &data_description) {
     data = data_description;
   }
 };

vs

 class Base {
   DataDescription data;
 protected:
   virtual DataDescription &get_data_description() = 0;
 public:
   Base() {
     data = get_data_description();
   }
 };

(おそらく速度が最適化されていませんが、これは現在は関係ありません)。 (ああ、C++コンストラクターが純粋仮想関数を呼び出すことができないことを忘れました。長い間C++を使用していませんでした。しかし、これは私の質問の本質を変えるものではありません)。

実際、私は現在Perlでプログラミングしています。

1
porton

データ構造を渡すことで、基本クラスのコンストラクターが子クラスによって定義された抽象メソッドを呼び出すときに発生する可能性のある潜在的なバグを防ぐことができます。

この潜在的なバグは、子クラスにコンストラクターで初期化されるメンバー変数がある場合に発生します。次に、抽象メソッドの実装は、メンバー変数が初期化されていることを前提としています。多くの言語では、基本クラスコンストラクターは常に子クラスコンストラクターの開始時に実行されます。これは、子クラスがそのメンバー変数を初期化する前に、基本クラスが抽象メソッドを呼び出すことを意味します。

Pythonでは、基本クラスのコンストラクターを呼び出す前にメンバー変数を初期化することで、これを回避できます。ただし、この問題を回避するには、この潜在的な問題を認識しておく必要があります。この回避策も使用できるかどうかについてコメントするのに十分なPerlがわかりません。

4
unholysampler