web-dev-qa-db-ja.com

すべてのクラスに、適切なコーディング規則の一部としてデフォルトのコンストラクターが必要です

これまでに読んだテキストから、慣習ではconstructorsがある場合、defaultから整理することについて説明しています。とにかく、すべてのクラスにdefault constructorが必要なのでしょうか。これは、少なくともclassの単純なインスタンスをオンザフライで作成するのに役立ちます。parameterized constructorを使用する必要はありません。これ自体は、特定のパラメータタイプに追加のimportsを必要とする場合があります。

5
Shamim Hafiz

一般的に言えば、作成されるオブジェクトを有効な状態に適切に初期化するのに十分なパラメーターを取るクラスのコンストラクターが必要です。クラスが、そのクラスのオブジェクトの有効な状態を構成するすべてのフィールドに適切なデフォルトを提供できる場合は、デフォルトのコンストラクターを使用することをお勧めします。

また、一部のライブラリーでは、特定の操作のためにデフォルトのコンストラクターの存在が必要です。たとえば、json/xmlの非直列化に使用されるJavaのライブラリは、実行時にすべてを評価しようとし、どのコンストラクタを事前に知ることができないため、リフレクションを介してデフォルトコンストラクタを呼び出す必要があることがよくあります。デフォルトのコンストラクターが必要な場合に、デフォルトのコンストラクターが必要ですが、ユーザーが制御するものやAPIのユーザーによって呼び出されるべきではない場合、一般的なイディオムを使用するのが最善です。コンストラクターをプライベートとしてマークするための言語(例:典型的な静的型付き言語でのプライベートアクセス)。

10
whaley

デフォルトのコンストラクタが意味をなさない2つのケースがあります。

  1. そのフィールドまたはプロパティへのクラスの依存。

    データベースから統計データを読み込み、それをチャートに表示する一連のクラスを想像してみてください。クラスの1つであるDataTransformは、チャートで使用するためにデータベースからのデータを正規化します。このクラスはIDataProviderを使用してDataTransformに生データをフィードします。

    テストと相互運用を可能にするために、IDataProviderを実装する4つのクラスがあります。1つはOracle用、1つはMicrosoft SQL Server用、もう1つはXMLから直接データをロードし、最後にユニットテストで使用するモックです。

    デフォルトのコンストラクタがあると、次のことを強制されます。

    • _IDataProvider dataProvider_フィールドが初期化されたことをDataTransformのほぼすべてのメソッドで確認します。

    • クラスを使用している人がパラメーター化されたコンストラクターを呼び出すか、デフォルトのコンストラクターを呼び出してから、追加のプロパティまたはメソッドを介してデータプロバイダーを設定することを期待します。

    これは、設計に重大な問題があることを示しています。デフォルトコンストラクターを破棄し、データプロバイダーをパラメーターとして取るコンストラクターのみを使用すると、クラスの使用がより直感的になり、独自のコードが単純になります。

  2. デフォルトが意味をなさない不変オブジェクト

    PersonFirstName、およびLastNameをプロパティとして持つ不変のBirthDateを想像してください。姓と名はデフォルトで空の文字列(または言語がnull文字列を許可する場合はnull)に設定できますが、誕生日は何になりますか?最小承認日? 名前がなく、1月1日に生まれた不変の人が必要なのはなぜですかst、1年目?

    不変性だけでは、デフォルトのコンストラクターが存在しないという意味ではないことに注意してください。たとえば、Pointのデフォルトコンストラクターを作成すると、Point(x = 0, y = 0)になります。別の方法は、静的定数_Point.Zero_を持つことです。別の例:不変のString(nullまたは空の文字列)のデフォルトコンストラクターを持つことは完全に理にかなっています。

7

一部のクラスが複雑なコンストラクターのみを持つことを選択する理由は、インスタンスに関するコア情報を知らなければ、それらが有効に機能できないことが多いためです。些細なインスタンスを作成できることは、この場合はメリットがありません。実際には、すべてのメソッドが重要なデータが欠落しているオブジェクトを処理できなければならないため、おそらくデメリットになります。これを許可しないことにより、多くの場合、コーディング時間と実行時の労力を大幅に節約するクラスの不変条件を確立できます。

どのコンストラクターを「すべき」か、または持つべきでないかについての一般的なルールは、そのようなクラス固有の考慮事項にほとんど影響を与えません。実際には、私がこれまでに見た簡単なコンストラクターを適用する唯一の有効な理由は、それ自体が必要なフレームワークにオブジェクトを渡す場合です。それでも、それを回避できる場合は、おそらくコンストラクタをプライベートにします。

5
Kilian Foth

絶対違う。デフォルトのctorは、クラスcanが外部からの情報なしで賢明に構築される場合に発生します。 (質問をそのサブセットに限定すると、答えは「はい」になります。)

それ以外の場合は、デフォルトのctorを使用すると、2段階の初期化が強制され、そこに発生するすべての欠点が発生します。

3
Balog Pal

コーディングスタイルと実装するパターンによって異なります。 Dependency Injection(DI)を使用すると、XMLシリアル化用など、実際に必要なときにデフォルトコンストラクターしか持たないことがよくあります。 DIでバイアスされているので、私はノーと言う傾向があります、コンストラクターで行われる唯一の作業はクラスの依存関係の注入なので、デフォルトのコンストラクターは必要ありません:コンストラクターは型の依存関係の静的ドキュメントになります。

2
Mathieu Guindon

私は毛布の全部または何も推奨が好きではありません。それらの条件だけでは、私はノーだと思います。

ケースバイケースで練習を検討してください。銀の弾丸はありません。

デフォルトのコンストラクターは、必要な場合にのみ作成してください。 YAGNIはより優れたコーディング規約です。

0
Joppe