2

Let's consider an example wherein I have to model the following:

  1. Class to schedule exams for a Student, lets call it StudentExamScheduler
  2. Class to schedule exam for a Class. Let's call it ClassExamScheduler and currently it depends on the logic provided by StudentExamScheduler.

So since both the classes schedule exams, I created an interface ExamScheduler which both the classes would implement. Reason being:

  • They are essentially scheduling exams
  • would give me the flexibility to swap the schedulers in-and-out as functionality changes.

This is how the interface would look:

interface ExamScheduler {
       scheduleExam(data);
}

Now each of my concrete class implements this interface and ClassExamScheduler now uses the StudentExamScheduler to delegate some responsibilities.

class ClassExamScheduler implements ExamScheduler {

  private ExamScheduler studentExamScheduler;

  public scheduleExam() {

    studentExamScheduler.scheduleExam();
    // do other stuff
  }
}

Is this a valid use of Interface & Composition? Typically I have seen Interface being used for polymorphism. But in this use case I use it to provide me flexibility to inject new classes when the requirements change.

  • What you have written here is an example of the Decorator design pattern, one of the most common uses of composition and polymorphism. There's certainly nothing wrong with this approach. – Jules Jul 7 '16 at 8:25
  • @Jules yeah it looks like a variant of decorator without any inheritance stuff. – AgentX Jul 7 '16 at 12:09
2

My two cents:

  • There's no contradiction between the use of interfaces and composition.
  • You are using polymorphism. Dependency injection and delegation are possible because of polymorphism.

A couple of observations:

  • The studentExamScheduler should be named examScheduler. Since you will be injecting it you should not name the variable after an specific implementos of ExamScheduler.
  • Consider creating a more generic Scheduler interface, with a schedule(ScheduleData data); such an interface could be implemented by any type of scheduler like LessonScheduler, MeetingScheduler etc.
  • My bad, I just tried to come up with a simple example of the problem I am trying to solve. Added the implements clause. – AgentX Jul 6 '16 at 14:19
  • @AgentX I deleted that observation and changed it for another one related to a more generic interface. – Tulains Córdova Jul 6 '16 at 14:38
  • Yes, it makes sense. I have tried to keep the interface generic in regards with the Business Process at hand. – AgentX Jul 6 '16 at 15:42
2

Using interfaces like this is usually an easy and clean way to provide flexibility. For example you could change the implementation of a ClassExamScheduler instance at runtime without modifying source code. This is possible by assigning studentExamScheduler another type of ExamScheduler that provide some other method of scheduling. This kind of polymorphism is one of the main benefits of using interfaces.

However

I don't see any real benefits of having ClassExamScheduler implement ExamScheduler. I see where you are going with the aspect of composition; since both classes schedule exams, they could implement a common method.

But this means that a ClassExamScheduler can implement it's .scheduleExam(..)-method by using another ClassExamScheduler instance as a middleman, which to me seems kind of odd and unnecessarily complicated.

Second, this structure could cause program failure if used without caution. If a ClassExamScheduler would implement a closed chain of ClassExamSchedulers like:

ClassExamScheduler A, B, C;
A.studentExamScheduler = B;
B.studentExamScheduler = C;
C.studentExamScheduler = A;

Or even itself:

ClassExamScheduler A;
A.studentExamScheduler = A;

You would end up with a recursive loop that would end in a stack overflow.

Regarding composition

I think that the subtle distinction here is that StudentExamScheduler schedules an exam and ClassExamScheduler uses an ExamScheduler (i.e. an StudentExamScheduler) to schedule an exam, indirectly.

  • I don't think that I understand your answer completely. In the Business Problem I am trying to solve, these StudentExamScheduler and ClassExamScheduler are a bit different. ClassExamScheduler currently needs a specific way of scheduling student's exams, the functionality is provided by StudentExamScheduler. Now StudentExamScheduler currently depends on specific framework which might change tomorrow. So using this approach I would get the flexibility that you mentioned. – AgentX Jul 6 '16 at 15:48
  • Is there something specific in my answer that you want me to make clear? My main point was that ClassExamScheduler won't have to implement ExamScheduler to achieve your desired functionality. Rather, making ClassExamScheduler implement ExamScheduler introduces risks of misuse since a ClassExamScheduler could provide this functionality, i.e. an instance of ClassExamScheduler could be your private ExamScheduler studentExamScheduler;. To utilize the interface you'd instead want to have different classes for different frameworks instead of changing StudentExamScheduler every time. – Supreme Barbarian Jul 6 '16 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.