2016-08-08 1 views
1

В чем проблема с вызовом метода caller и Callee двух разных классов, выполняющих вызовы различных методов класса на круговом уровне. Вы передаете эту «эту» ссылку в качестве параметра для какого-либо другого метода экземпляра класса, а Callee делает дополнительное приглашение метода на вызывающем, которое передается как параметр.Метод Caller и Callee, вызовы метода класса класса

Одна из причин этого. В классе фабрики различным реализациям нужны разные виды данных, поэтому вы помещаете данные, которые необходимы в виде нескольких методов контрактов/интерфейсов, и реализуют их вызывающий. Если у вас есть только один класс, проще реализовать инкапсуляцию, но разные классы требуют разных наборов данных.

Ниже приведен простой пример: здесь StudentService вызывает метод topscorer MathClassScorer, который, в свою очередь, вызывает метод getStudentList от StudentService. В сложном сценарии вы можете вызвать несколько методов родительского вызова.

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

Ну, вся тема ОО немного противоречивая, я боюсь. Но, на мой взгляд, проблемы с указанным выше кодом начинаются с наименования ваших классов. IStudentData не является объектом. Удержание некоторых данных - это не ответственности, а объектам требуются обязанности.

Тогда дизайн требует, чтобы объекты IScore знали о внутреннем содержимом данных IStudentData, не обращая внимания на объект полностью. Код также предполагает, что IScore должен знать о внутренней работе Student.

Хороший дизайн OO - это то, где объекты фактически имеют обязанности, а их данные видны как можно меньше, в идеале - совсем не так.

Таким образом, не зная всех подробностей, вот что ваши объекты могут выглядеть следующим образом:

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 (Сервис в вашем коде) не должен выставлять список учеников, вместо этого он должен предоставлять методы на самом деле do.

+0

Спасибо за ответ. Это работает, если есть только Math (isBetterAtMathThan)., Я могу скрыть свои данные или передать только необходимую информацию. Причиной для Factory является: может быть другой Scorer, который может зависеть от разных наборов данных. – coder000001

+0

Но, я согласен с вашими точками. Но можете ли вы обратиться к этому с помощью различных реализаций, таких как Factory, которые я опубликовал! – coder000001

+0

Я должен был бы знать, какова ваша цель/требование. Обычно все «скоринг» следует делать в «Студенте», так как данные есть. Затем другие классы могут выбрать, какой скоринг нужен. Если вы действительно хотите, чтобы это было «подключаемым» (только если это действительно нужно), вам нужно будет создать абстракцию, которая не требует получения данных из «Студент». Возможно, он может быть поставлен во время строительства «бомбардира». –