Question

Le code suivant casse loi de Déméter :

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

Questions

  1. Comment le LOD brisé?
  2. Où est le code briser le LOD?
  3. Comment le code doit être écrit à respecter la limite de détection?
Était-ce utile?

La solution

Méthodes en classe des étudiants qui enfreignent la loi de Déméter sont

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

parce que ce domaine exposer des objets Grades et enseignant à l'application.

En supposant que vous souhaitez continuer à cacher les Grades à l'intérieur d'un étudiant et un enseignant à l'intérieur Grades, une façon de remédier à ce problème est de définir des méthodes proxy (également appelées méthodes de délégués) dans des étudiants de classe qui fonctionnent sur les Grades internes et enseignants des objets au nom de l'application, similaire à la méthode Student.isTeacher(int, String). Cette solution peut conduire à la duplication des méthodes Grades et enseignant en étudiant qui est un d'une conception de classe qui respecte le LofD.

Une meilleure solution serait de supprimer le classement et l'enseignant de l'élève et de les mettre tous dans une autre classe, dire Transcript:

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

Autres conseils

Je pense que voici deux problèmes:

  1. logique de Grades est trop mélangé avec Student. Il devrait être fait en classe Grades
  2. la logique de Teacher est placé dans Student.

Conclusion: L'étudiant sait trop sur la structure interne et la logique des enseignants et Grades et qui brise LOD

La plupart des problèmes tels que celui-ci peuvent être résolus en revisitant votre modèle de domaine.

Il semble que l'étudiant a la responsabilité de façon plus que prévu. Il devrait y avoir qu'une seule raison de changer.

Je factoriser en ajoutant un objet ReportCard.

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 "atteint par" selon l'article de wikipedia que vous mentionnez.

J'ai été surpris de trouver la liste des grades une propriété de l'étudiant. Il ne faut pas que quelque chose l'école connaît et gère? Je demande à l'école, enseignant classé un étudiant en quelle année ...

En ayant ces deux fonctions privées casse LOD.

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

Les étudiants ne devraient pas avoir la logique pour pour effectuer ces tâches.

La façon dont je redessiner est de séparer les données de la logique. L'élève doit uniquement être données uniquement. Il doit contenir des informations sur l'élève et l'étudiant ne. Par conséquent, cela ne comprend pas Grades que ce concept exige d'autres, comme sujet, et professeur.

La même chose vaut pour l'enseignant. Je puis créer un endroit pour stocker des informations de qualité et un autre lieu d'information sujet.

Pour effectuer des tâches similaires que je ferais ceci:

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

Où sujet est également une donnée unique objet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top