Frage

Der folgende Code bricht das Gesetz von Demeter :

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;
  }
}

Fragen

  1. Wie wird die LoD gebrochen?
  2. Wo ist der Code die LoD brechen?
  3. Wie sollte der Code geschrieben werden, um die LoD zu wahren?
War es hilfreich?

Lösung

Methoden in der Klasse Schüler, die das Gesetz von Demeter brechen sind

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

, weil diese entlarven Domain-Objekte Sorten und Lehrer an die Anwendung.

Unter der Annahme, dass Sie möchten die Noten innerhalb eines Studenten und einem Lehrer innerhalb Grades zu verstecken, um fortzufahren, eine Möglichkeit, dieses Problem zu beheben, ist Proxy-Methoden zu definieren (auch Delegatmethoden genannt) in der Klasse Schüler, die auf den inneren Qualitäten und Lehrer arbeiten Objekte im Namen der Anwendung, ähnlich wie bei Methode Student.isTeacher(int, String). Diese Lösung kann zu Doppel Methoden in den Klassen und Lehrern in Studenten führt, die ein Nachteil eine Klasse Design, das das LofD respektiert.

Eine bessere Lösung wäre es, die Klasse und Lehrer von Schülern zu entfernen und sie alle in einer anderen Klasse setzen, sagen Transcript:

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

Andere Tipps

Ich denke hier, dass es zwei Probleme:

  1. Grades Logik zu sehr mit Student gemischt. Es sollte in Grades Klasse durchgeführt werden
  2. Teacher Logik in Student gestellt.

Fazit: Student weiß zu viel über innere Struktur und Logik der Lehrer und Noten, und dass Pausen LoD

Die meisten Probleme, wie dies durch erneuten Besuch Ihrer Domain-Modell gelöst werden.

Es sieht aus wie der Student hat viel mehr Verantwortung als es sollte. Es sollte nur ein Grund zu ändern hat.

Ich würde das Refactoring durch eine Reportcard Objekt hinzugefügt wird.

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 "erreicht durch" nach dem Wikipedia-Artikel Sie erwähnen.

Ich war überrascht, die Liste der Qualitäten eine Eigenschaft des Studenten zu finden. Sollte das nicht etwas sein, die Schule kennt und verwaltet? Ich würde die Schule bitten, die Lehrer einen Schüler in dem Jahr abgestuft ...

Durch diese beiden privaten Funktionen Pausen LOD mit.

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

Die Schüler sollten nicht brauchen die Logik auf solche Aufgaben auszuführen.

So wie ich diese Neugestaltung würde ist, Daten von der Logik zu trennen. Student sollte eine reine Daten nur sein. Es sollte nur Informationen über die Schüler und Studenten enthalten. Daher schließt dies nicht die Klasse wie das Konzept andere wie Thema erfordert, und Lehrer.

Das gleiche gilt für Lehrer. Ich würde dann einen Platz zum Speichern von Informationen Grad und einer anderen Ort für ein Objekt Informationen erstellen.

Um ähnliche Aufgaben ausführen würde ich dies tun:

gradesDatabase.getGrade(subject, student);
subjectDatabase.getTeacher(subject, student);

Wo Thema ist auch ein Datum nur Objekt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top