2016-08-08 15 views
1

循環呼び出しのクラス・レベルの異なるメソッド呼び出しを行う2つの異なるクラスのメソッド呼び出し元と呼び出し先の問題点は何ですか?他のいくつかのクラスインスタンスメソッドへのパラメータとして "this"参照を渡し、パラメータとして渡された呼び出し側のさらなるメソッド招待をCalleeが行っています。メソッド呼び出し元と呼び出し先、循環クラス・レベルのメソッド呼び出し

ファクトリクラスでは、さまざまな実装が異なる種類のデータを必要とするため、必要なデータを複数のコントラクト/インターフェイスメソッドとして配置し、呼び出し元に実装させます。クラスが1つしかない場合、カプセル化を実装する方が簡単ですが、のクラスでは異なるデータセットが必要です

以下はその簡単な例です。ここでStudentServiceはMathClassScorerのtopscorerメソッドを呼び出し、StudentServiceのgetStudentListメソッドを呼び出します。複雑なシナリオでは、親呼び出し元の複数のメソッドを呼び出すことがあります。

public interface IStudentData { 
    public List<Student> getStudentList(); 
} 

public class StudentService implements IStudentData { 
     private List<Student> studentList; 

     public String getTop() { 
      // Factory returns MathClassScorer 
      IScore scorer = ClassScorerFactory.get(); 
      return scorer.topscorer(someOtherData, this); 
     } 

     @Override 
     public getStudentList() { 
      // do something and return studentList; 
      return studentList; 
     } 

} 

// IScore contains topscorer method 
public class MathClassScorer implements IScore { 

    @Override 
    public String topscorer(Map someOtherData, IStudentData data) { 
     List<Student> studentList = data.getStudentList(); 
     //do something before and after 
     return SOMETHING_AFTER 
    } 
} 

質問は、上記の方法に問題がありますか?

+1

これは問題ありません。 – Andreas

+0

質問は何ですか? – k3b

+0

質問は、アプローチに問題はありますか? – coder000001

答えて

0

これは問題ありません。 Strategy patternとして知られている一般的な方法です。

このような注入を使用することは、モックオブジェクトを供給することによって、ロジックをデカップリングし、各コンポーネントのユニットテストを可能にする非常に便利なテクニックです。

+0

戦略パターンは参照を一方向に行います。ここでは、私たちは循環している! – coder000001

1

OOの全体的な話題は少し議論の余地があります。私は恐れています。しかし、私の意見では、上記のコードの問題はクラスの命名から始まります。 IStudentDataはオブジェクトではありません。一部のデータを保持するのはで、責任はであり、オブジェクトには責任が必要です。

次に、IStudentDataの内部データの内容についてオブジェクトが完全に無視されるように設計する必要があります。このコードでは、IScoreStudentの内部動作について知る必要があることを示しています。

良いオブジェクト指向設計は、オブジェクトに実際に責任があり、データができるだけ目に見えない、理想的には全く表示されないデザインです。

だから、すべての詳細を知らなくても、ここにあなたのオブジェクトは、次のようになりものです:あなたが本当に異なる同等のスキルのカップルを超える一般化したい場合は、その後、あなたはまだそれを行うことができ、

public class Student { 
    public boolean isBetterAtMathThan(Student other) { 
     ... 
    } 
} 

public class Students { // or StudentRepository 
    public Student getBestStudentAtMath() { 
     return students.stream().max(toComparator(Student::isBetterAtMathThan)).get(); 
    } 
} 

か学生からのデータを公開することなく:ポイントがある

public class Students { 
    public Student getBestStudentAt(Comparator<Student> skillComparator) { 
     return students.stream().max(skillComparator).get(); 
    } 
} 

Studentは、データを公開しますが、操作を提供する、またはものを行うことができ、他のオブジェクトを作成するべきではありません。同様に、Students(あなたのコード内のサービス)は生徒のリストを公開するべきではなく、実際にを実行するメソッドを提供する必要があります。

+0

返事をありがとう、これは数学(isBetterAtMathThan)のみがある場合に動作します。私は自分のデータを隠すか、必要な情報だけを渡すことができます。ファクトリーに行く理由は、異なるデータセットに依存する可能性のある別のScorerがあることです。 – coder000001

+0

しかし、私はあなたの意見に同意します。しかし、私が掲載したFactoryのような異なる実装でこれを対処できますか? – coder000001

+0

私はあなたの目標/要件が何であるか知っていなければなりません。通常、データはそこにあるので、「得点」はすべて「スチューデント」で行われます。他のクラスでは、どのスコアリングが必要かを選択できます。本当にこれを 'プラグイン可能'にしたい場合(本当に必要な場合のみこれを行う)、 'Student'からデータを取得する必要のない抽象化を作成する必要があります。おそらく、「得点者」の建設中に供給されるかもしれない。 –

関連する問題