この暗号はどのようにしてデメテルの法則を破るのでしょうか?

StackOverflow https://stackoverflow.com/questions/2609236

  •  25-09-2019
  •  | 
  •  

質問

次のコードは、 デメテルの法則:

public class Student extends Person {
  private Grades grades;

  public Student() {
  }

  /** Must never return null; throw an appropriately named exception, instead. */
  private synchronized Grades getGrades() throws GradesException {
    if( this.grades == null ) {
      this.grades = createGrades();
    }

    return this.grades;
  }

  /** Create a new instance of grades for this student. */
  protected Grades createGrades() throws GradesException {
    // Reads the grades from the database, if needed.
    //
    return new Grades();
  }

  /** Answers if this student was graded by a teacher with the given name. */
  public boolean isTeacher( int year, String name ) throws GradesException, TeacherException {
    // The method only knows about Teacher instances.
    //
    return getTeacher( year ).nameEquals( name );
  }

  private Grades getGradesForYear( int year ) throws GradesException {
    // The method only knows about Grades instances.
    //
    return getGrades().getForYear( year );
  }

  private Teacher getTeacher( int year ) throws GradesException, TeacherException {
    // This method knows about Grades and Teacher instances. A mistake?
    //
    return getGradesForYear( year ).getTeacher();
  }
}

public class Teacher extends Person {
  public Teacher() {
  }

  /**
   * This method will take into consideration first name,
   * last name, middle initial, case sensitivity, and
   * eventually it could answer true to wild cards and
   * regular expressions.
   */
  public boolean nameEquals( String name ) {
    return getName().equalsIgnoreCase( name );
  }

  /** Never returns null. */
  private synchronized String getName() {
    if( this.name == null ) {
      this.name == "";
    }

    return this.name;
  }
}

質問

  1. LoDはどのように壊れるのでしょうか?
  2. LoD を破壊するコードはどこにありますか?
  3. LoD を維持するにはコードをどのように記述する必要がありますか?
役に立ちましたか?

解決

デメテルの法則を破るクラスの学生のメソッドです。

private Grades getGradesForYear( int year )
private Teacher getTeacher( int year )

これらの公開ドメインためには、アプリケーションへのグレードと教師オブジェクトます。

この問題を解決する一つの方法は、内部のグレードと教師を操作するクラスの学生で(もデリゲートメソッドと呼ばれる)、プロキシのメソッドを定義することで、あなたは学年内部学生と教師の内部グレードを非表示にし続けたいと仮定すると、メソッドのStudent.isTeacher(int, String)に似たアプリケーションの代わりにオブジェクト。この溶液は、欠点にある学生にグレードと教師のメソッドの複製をもたらし得ますLofDを尊重し、クラスのデザインます。

より良い解決策は学生からのグレードや教師を削除し、すべての別のクラスに入れて、トランスクリプトを言うことであろう

class Transcript {
  Student student;
  Teacher teacher;
  Grades grades;
  Integer year;
}  

他のヒント

ここには次の 2 つの問題があると思います。

  1. Grades ロジックが混ざりすぎている Student. 。で行うべきです Grades クラス
  2. Teacherのロジックは に配置されます Student.

結論:生徒は教師と成績の内部構造とロジックを知りすぎているため、LoD が壊れます

このようなほとんどの問題は、あなたのドメインモデルを見直すことで解決することができます。

学生は、道より責任それが必要以上を持っているように、

に見えます。それは変更に一つだけの理由を持っている必要があります。

私はレポートカードのオブジェクトを追加することで、これをリファクタリングします。

public class ReportCard
{
  public Student Student...
  public int Year...
  public ReportCardItem[] ReportCardItems...

  getGrades()...
  createGrades()...
}

public class ReportCardItem
{
  public Grade Grade...
  public string Subject...
  public Teacher Teacher...
}

Person.isTeacher "リーチスルー" あなたが言及Wikipediaの記事によるます。

はIは等級のリスト学生のプロパティを見つけるために驚きました。学校は知っていて、管理して何かをすべきではないということ?私は先生がどの年に学生を段階的学校に、お願いしたい...

ブレークがLODこれら2つのプライベートの機能を有することにより、

private Grades getGradesForYear( int year )
private Teacher getTeacher( int year )

学生は、このようなタスクを実行するためのロジックを必要はありません。

私はこれを再設計ような方法は、ロジックからデータを分離することです。学生は、純粋にデータだけでなければなりません。それだけで、学生と学生に関する情報が含まれている必要があります。その概念は、件名、教師として他人を必要とするので、これはグレードが含まれていません。

同じことは、教師のために行きます。私は、店のグレード情報と被写体情報のための別の場所に場所を作成することになります。

私はこれを行うだろう同様のタスクを実行するには

gradesDatabase.getGrade(subject, student);
subjectDatabase.getTeacher(subject, student);
被験体はまた、データオブジェクトのみ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top