Is there a way to forward-declare interfaces to avoid module interdependencies?
Per Ångström
d-news at autark.se
Thu Nov 11 04:10:15 PST 2010
I hope we can all agree that minimizing module interdependencies is a
good thing, that a highly interdependent set of modules is generally
harder to understand and more difficult to test than if the
module-dependency chain is acyclic.
With that in mind, suppose I have the following C++ code, organized with
a separation of interface and implementation, with no circular include
dependencies:
// IStudent.h
class ITeacher; // forward reference
class IStudent {
public:
virtual void ask(ITeacher &) = 0;
virtual void learn(ITeacher &, const char * knowledge) = 0;
};
// ITeacher.h
class IStudent; // forward reference
class ITeacher
{
public:
virtual void teach(IStudent &) = 0;
};
// Student.h
#include "IStudent.h"
class Student : public IStudent {
public:
void ask(ITeacher &);
void learn(ITeacher &, const char * knowledge);
};
// Teacher.h
#include "ITeacher.h"
class Teacher: public ITeacher {
public:
void teach(IStudent &);
};
// Student.cpp
#include "Student.h"
#include "ITeacher.h"
void Student::ask(ITeacher & teacher)
{
teacher.teach(*this);
}
void Student::learn(ITeacher &, const char * )
{
}
// Teacher.cpp
#include "Teacher.h"
#include "IStudent.h"
void Teacher::teach(IStudent & student)
{
student.learn(*this, "knowledge");
}
// main.cpp
#include "Student.h"
#include "Teacher.h"
int main()
{
Student student;
Teacher teacher;
student.ask(teacher);
return 0;
}
Below is my attempt at porting the code to D2. I hope I'm missing
something due to my limited experience with D, but it seems D forces me
to create circular dependencies between modules ITeacher and IStudent,
since I cannot find a way to forward-declare types external to the
current module in D like in C/C++.
// IStudent.d
import ITeacher; // would like to forward-declare the interface instead
interface IStudent {
void ask(ITeacher);
void learn(ITeacher, string knowledge);
}
// ITeacher.d
import IStudent;
interface ITeacher
{
void teach(IStudent);
}
// Student.d
import IStudent;
class Student : IStudent {
void ask(ITeacher teacher)
{
teacher.teach(this);
}
void learn(ITeacher teacher, string knowledge)
{
}
}
// Teacher.d
import ITeacher;
import IStudent;
class Teacher: ITeacher {
void teach(IStudent student)
{
student.learn(this, "knowledge");
}
}
// main.d
import Student;
import Teacher;
void main()
{
auto student = new Student;
auto teacher = new Teacher;
student.ask(teacher);
}
So my question is: Am I missing something, or is this the D way to do it?
Cheers,
--
Per Å.
More information about the Digitalmars-d-learn
mailing list