0

引数がオブジェクト内に含まれている場合にメソッドへの引数を検証するためのベストプラクティスについて質問があります。たとえば、次の場合:

public class Student {
   public int getStudentId();

   public String getStudentName();

   public String getStudentSSN();

   public double getStudentGpa();

   public String getStudentMajor();

   // Other student related getters
}

次に、メソッドがあります。

public void printStudentReport(Student student);

この方法では、ID、名前、GPA、およびメジャーを含むロジックを実行する必要があります。だから、それらは必要なものです。他のすべての学生ゲッターは、入力する必要はありません。最初にStudentオブジェクトを検証してから、必要な4つのメソッドを検証しても大丈夫ですか?このStudentオブジェクトをこのメソッドに渡すので、これは少し誤解を招くように感じますが、すべてのフィールドが必須というわけではないため、実際には半分の人口のオブジェクトがこのメソッドに送信されます。私には奇妙に思えます。

4

7 に答える 7

2

Studentを有効にするために一部のプロパティに常に値を設定する必要がある場合は、必要なパラメーターを使用してデフォルト以外のコンストラクターを定義し、クラスからデフォルトのコンストラクターを削除することを検討する必要があります(必要に応じて、ゲッター内のプロパティ値を検証します)。これにより、有効なStudentオブジェクトのみを作成できるようになります。

他のプロパティが学生にとって本当にオプションである場合、それは私には完全に問題ないように見えます。もちろん、どのパラメーターが必須でどれがオプションであるかを決定するために、ユースケースを検討し、ドメインモデルを注意深く分析する必要があります。

于 2010-07-28T16:12:23.540 に答える
1

作成しているコンセプトについて考えてみてください。学生レポートです。レポートの現在の要件は学生データのセットのみであるため、メソッドが学生データのセットのみを使用することは問題ではありません。多分彼らは将来変わるでしょう。多分彼らはそうしないでしょう。しかし、変更に対する耐性が高いため、適切な設計のように思えます。

現在、検証はより複雑です。レポートには、学生の通常の検証とは異なる、特別な種類の検証が必要ですか?その場合は、必ず、レポートで検証してください。

public void printStudentReport(Student student) {
  validateStudent(student);
  // print the report....
}

ただし、検証が一連のクライアント(おそらくforprintStudentReportおよびfor saveStudentInDatabase)に共通している場合は、検証クラスを作成できます。

public class FloogleStudentValidator { // or some good name that tells us what this validation does
  public void validate(Student student) { }
}

// ...

public void printStudentReport(Student student) {
  new FloogleStudentValidator().validate(student);
  // print the report....
}

生徒の検証の種類ごとに異なるクラスがあります。

ただし、検証がシステム全体に共通している場合は、それをStudentクラス自体に配置するか、学生インスタンスに入力されたとおりに検証することをお勧めします。

public void printStudentReport(Student student) {
  student.validate();
  // print the report....
}
于 2010-07-28T16:29:02.377 に答える
0

Studentからの属性が4つだけ必要な場合は、メソッドを変更して個別に取得することを強くお勧めします。

そうすることで、印刷方法をStudentから切り離し、すべてのメリットを得ることができます。

于 2010-07-28T16:16:06.517 に答える
0

1つのオプションは、Studentオブジェクトに、作成時(および編集中)のデータを検証させることです。これにより、Studentオブジェクトを渡している間、それらが有効であることを常に確認できます。

ただし、これには、プログラムのすべての領域で同じ検証制約がStudentオブジェクトに適用されるため、オプションではない可能性があるという前提があります。

于 2010-07-28T16:18:03.407 に答える
0

半分人口のオブジェクトは非常に一般的です。特に、オブジェクトにデータを取り込むデータソースを制御できない場合。printStudentReport()に必要なStudentフィールドのみを検証するだけで十分だと思います。私はよく、必要なデータに基づいて検証する同様のレポート生成メソッドを作成しますが、オブジェクトが存在する場合は、オブジェクトから追加のデータを提供します。

于 2010-07-28T16:21:02.200 に答える
0

学生オブジェクトを渡す代わりに、インターフェイスアプローチを試すこともできます。これは、オブジェクトのその部分のみを実装する学生オブジェクトを持つことができることを意味します。

public void printStudentReport(MyInterface student)

インターフェイスには、検証用のメソッドを含めることができます

于 2010-07-28T16:21:11.967 に答える
0

私が思い浮かぶ質問の1つは、ロジックが本当にレポートロジックなのか学生ロジックなのかということです。レポートでは、次のようにコーディングできます。

  thing = (student.getX() + student.getY() ) * student.getZ();

あるいは単に

  thing = student.getThing();

私の考えでは、おそらくいくつかのものは学生のものです。

したがって、X、Y、またはZの一部が正しく初期化されていないため、計算できないというケースが発生します。したがって、getThing()を呼び出すと例外がスローされる可能性がありますが、それは奇妙に感じます。オブジェクトがgetThing()機能を提供する必要があるのに、それを実行できないのはなぜですか?

あなたのStudentクラスはリファクタリングを必要としているようです。学生が実行できる機能のコアセットがあり、特定のレポートを作成するのに十分です。したがって、IRegisteredインターフェイスとより豊富なIActiveStudentインターフェイスがあります。レポートクラスにはIRegisteredが必要であり、他のクラスにはIActiveStudentが必要です。

Caterpillerが蛾に変わるように、さまざまなStudentオブジェクトが生涯で能力を変更します。caterpillerにはfly()メソッドがないため、すべてのlepidoptraクラスにcanYouFlyYet()メソッドは必要ありません。

于 2010-07-28T16:26:00.743 に答える