これが1つのアプローチです。を複合パターンClassRoom
のインスタンスとして扱い、階層内のすべてのオブジェクトが. オブジェクトがすでに入力されている場合、それ自体を返すことによって、それ自体を入力するように求められることに応答します。入力されていない場合は、から必要な情報を取得し、入力された独自のクラスの新しいインスタンスを構築します (したがって、オブジェクト自体は不変です。オブジェクト自体を変更することを好むかもしれませんが、私は通常、不変オブジェクトを使用してデータを表す)。DataCollector
DataCollector
Fillable
自分自身を埋める方法を知っているオブジェクトのインターフェイスを定義しました。ただし、fillIn
メソッドが多態的に呼び出されることはないため、これは実際には必要ありません。本当にただのドキュメントです。
記入プロセスは非常に簡単だと思います。明らかに、何が埋められているかを検出すること (例えば、生徒の空のリストは、リストが入力されていないことを示している可能性があります) と、それがどのように埋められるかの両方において、より複雑になる可能性があります。実際の問題として、DataCollector
が非常に複雑になることがわかります。別の因数分解が必要になります。ClassRoomInfoDataCollector
コレクション ロジックの多くをドメイン クラスに移動したり、クラスごとの DAO (など)に分割したりすることができます。
public interface Fillable<T> {
public T fillIn(DataCollector collector);
}
public class ClassRoom implements Fillable<ClassRoom> {
private final ClassRoomInfo classRoomInfo;
private final List<Student> students;
private ClassRoom(ClassRoomInfo classRoomInfo, List<Student> students) {
this.classRoomInfo = classRoomInfo;
this.students = students;
}
@Override
public ClassRoom fillIn(DataCollector collector) {
ClassRoomInfo filledInClassRoomInfo = classRoomInfo.fillIn(collector);
List<Student> filledInStudents = new ArrayList<Student>();
for (Student student : students) {
filledInStudents.add(student.fillIn(collector));
}
if (filledInClassRoomInfo == classRoomInfo && filledInStudents.equals(students)) return this;
return new ClassRoom(filledInClassRoomInfo, filledInStudents);
}
}
public class ClassRoomInfo implements Fillable<ClassRoomInfo> {
final String roomNumber;
final Integer capacity;
private ClassRoomInfo(String roomNumber, int capacity) {
this.roomNumber = roomNumber;
this.capacity = capacity;
}
@Override
public ClassRoomInfo fillIn(DataCollector collector) {
if (capacity != null) return this;
return new ClassRoomInfo(roomNumber, collector.getClassRoomCapacity(roomNumber));
}
}
public class Student implements Fillable<Student> {
final int id;
final String name;
private Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public Student fillIn(DataCollector collector) {
if (name != null) return this;
return new Student(id, collector.getNameOfStudent(id));
}
}
public class DataCollector {
public String getNameOfStudent(int id) {
...
}
public int getClassRoomCapacity(String roomNumber) {
...
}
}