CS 696: Advanced OO
| Law of Demeter | slide # 2 |
| ...Benefits | slide # 6 |
| ...Law of Demeter and God Classes | slide # 7 |
| ...Law of Demeter and Container Classes | slide # 10 |
Lieberherr, Holland, Riel, Object-Oriented Programming: An Objective Sense of Style, OOPSLA 1988 Proceedings
Lieberherr, Adaptive Object-Oriented Software: The Demeter
Method with Propagation Patterns, PWS Publishing Company,
1996
class Course {
Instructor boring = new Instructor();
int pay = 5;
public Instructor getInstructor() { return boring; }
public Instructor getNewInstructor() {return new Instructor(); }
public int getPay() {return pay; }
}
class C {
Course test = new Course();
public void badM() {
test.getInstructor().fired();
}
public void goodM() {
test.getNewInstructor().hired();
}
public int goodOrBadM?() {
return getpay() + 10;
}
}
class Course {
Instructor boring = new Instructor();
int pay = 5;
public Instructor fireInstructor() { boring.fired(); }
public Instructor getNewInstructor() { return new Instructor();}
public int getPay() { return pay ; }
}
class C {
Course test = new Course();
public void reformedBadM() {
test.fireInstructor();
}
public void goodM() {
test.getNewInstructor().hired();
}
public int goodOrBadM() {
return getpay() + 10;
}
}
class Course {
Instructor boring = new Instructor();
int pay = 5;
public Instructor fireInstructor() { boring.fired(); }
public Instructor hireNewInstructor() { boring = new Instructor();}
public int getPay() { return pay ; }
}
class C {
Course test = new Course();
public void reformedBadM() { test.fireInstructor(); }
public void goodMImproved() { test.hireNewInstructor();}
public int goodOrBadM() {
return getpay() + 10;
}
}Assume that Student and Scores are basicly structs with lots of get/set methods and Course does all the work
class Student
{
Scores exams = new Scores();
public Scores getExamScores()
{ return exams; }
public Scores setExamScores( Scores newScores)
{ exams = newScores;}
// stuff missing
}
class Course
{
Student[] enrolled = new Student[ 40 ];
public void computeAverage( int studentIndex )
{
Scores toCompute =
enrolled[ studentIndex].getExamScores();
float sum = 0;
for ( int k = 0; k < toCompute.length(); k ++ )
sum += toCompute.gradeAt( k );
}
}
Law of Demeter and God ClassesCompare coupling in two examples
class StudentImproved
{
Scores exams = new Scores();
public int computeAverage()
{
// compute average here;
}
public Scores setExamScores( Scores newScores)
{
exams = newScores;
}
}
class Course
{
StudentImproved[] enrolled = new StudentImproved[ 40 ];
public void computeAverage( int studentIndex )
{
int average = enrolled[ studentIndex].computeAverage();
}
}
class Student
{
Scores exams = new Scores();
public Scores getExamScores() { return exams; }
public Scores setExamScores( Scores newScores)
{ exams = newScores;}
// stuff missing
}
class Course
{
Student[] enrolled = new Student[ 40 ];
public void computeAverage( int studentIndex )
{
computeStudentAverage(
Student[ studentIndex].getExamScores());
}
public void computeStudentAverage( Score exams )
{
float sum = 0;
for ( int k = 0; k < exams.length(); k ++ )
sum += exams.gradeAt( k );
}
}
class Test
{
public void ok( Scores exam, Scores homework )
{
exam.hereIsAMethodCall();
homework.hereIsAMethodCall();
}
public void seemsOK( Scores[2] gradeEvents )
{
gradeEvents[0].hereIsAMethodCall();
gradeEvents[1].hereIsAMethodCall();
}
public void seemsNotOK( Vector gradeEvents )
{
gradeEvents.at(0).hereIsAMethodCall();
gradeEvents.at(1).hereIsAMethodCall();
}
}