I have a hierarchical class structure. Let's say I am modelling students in a city:
class District {
private Map<String, School> schools;
public School getSchool(String name) {
School school = schools.get(name);
if (school == null) {
school = new School();
schools.put(name, school);
return school;
}
}
and
class School {
private Map<String, Classroom> classrooms;
public Classroom getClassroom(String name) {
// similar lazy init code
}
}
and
class Classroom {
private Map<String, Pupil> pupils;
public Pupil getPupil(String name) {
// similar lazy init code
}
}
and finally
class Pupil {
private PupilProfile profile = new DefaultPupilProfile();
}
Each object is dynamically and lazily created as it is required.
Now lets say I want to use different implementations of PupilProfile depending on (for sake of argument) the pupil's age. However, I don't want to put the logic of which PupilProfile implementation is used in Pupil - I want to separate it out. I may want to change it in future.
I write a factory interface:
interface PupilProfileFactory {
PupilProfile newPupilProfile(Pupil pupil);
}
and my initial implementation:
class AgeDependentPupilProfileFactory implements PupilProfileFactory {
@Override
public PupilProfile newPupilProfile(Pupil pupil) {
switch (pupil.getAge()) {
// Case statements returning different implementations
}
}
}
This implementation exists as a singleton in my application (eg in the Spring app context).
My problem is that I now have to get this factory into the Pupil:
class Pupil {
private PupilProfile profile = new DefaultPupilProfile();
public Pupil(PupilProfileFactory factory) {
this.profile = factory.newPupilProfile(this);
}
}
In practise this means passing the PupilProfileFactory down every layer of the object graph, from top (District) to bottom (Pupil) via constructors or setters. Each intermediate layer needs to have a field for this factory, even though they only use it to pass it down to the level below when they lazily create one.
This strikes me as ugly (and a pain to refactor) and I'm sure there must be a better way - is there?
Aucun commentaire:
Enregistrer un commentaire