方法Caller和Callee,循环类级方法调用

时间:2016-08-08 14:39:40

标签: java oop interface polymorphism higher-order-functions

执行循环类级别不同方法调用的两个不同类的方法调用者和被调用者有什么问题。你通过"这" reference,作为其他类实例方法的参数,Callee在调用者上做进一步的方法邀请,作为参数传递。

这样做的一个原因是,在工厂类中,不同的实现需要不同类型的数据,因此您将所需的数据作为多个合同/接口方法放置并让调用者实现它们。如果您只有一个类,则更容易实现封装,但不同的类需要不同的数据集

以下是此类简单示例,此处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
     }
} 

问题是,上述方法有问题吗?

2 个答案:

答案 0 :(得分:1)

嗯,OO的整个话题有点争议我害怕。但在我看来,上面代码的问题始于你的类的命名。 IStudentData不是对象。持有一些数据不是责任,对象需要责任。

然后,设计要求IScore对象知道IStudentData的内部数据内容,完全忽略该对象。该代码还建议IScore也需要了解Student的内部工作原理。

良好的面向对象设计是对象实际上有责任的地方,并且他们的数据尽可能少地显示,理想情况下根本不可见。

因此,在不知道所有细节的情况下,以下是您的对象的样子:

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(代码中的服务)不应公开学生列表,而应提供实际内容的方法。

答案 1 :(得分:0)

这样做没有问题。这是一种常见的做法,称为Strategy pattern

使用这样的注入是一种非常有用的解耦逻辑技术,允许通过提供模拟对象对每个组件进行单元测试。