让我们说,我有一个复杂的对象层次结构,如:
public class ClassRoom
{
private ClassRoomInfo classRoomInfo;
private List<Student> students;
...
}
我将此对象作为客户端的输入,但该对象可能无法完全填充。例如,客户端可以在studentId(s)
对象中提供非常小的详细信息,如classRoomInfo
或次要信息。我想为这个对象编写一个DataCollector
类,它会预先收集所有丢失的数据。
在这种情况下,最好的设计模式是什么?
答案 0 :(得分:2)
我认为您需要在需要时延迟加载数据。ClassRoom
类成员的getter应该足以满足此目的。
不建议使用单独的DataCollector
类,因为它会强制您在ClassRoom
中为所有成员公开setter。
此link(和Book)应该会告诉您有关延迟加载的更多信息。
答案 1 :(得分:2)
这是一种方法。我们的想法是将ClassRoom
视为composite pattern的一个实例,其中层次结构中的每个对象都知道如何使用DataCollector
“填充”。如果一个物体已经被填满,它会响应被要求通过返回来填补自己;如果它没有填写,它从DataCollector
获取必要的信息,并构建一个自己的类的新实例,它被填充(对象本身因此是不可变的 - 你可能更喜欢让对象自己变异,但我通常倾向于使用不可变对象来表示数据。)
我已经为知道如何填充自己的对象定义了一个接口Fillable
。但是,这并不是必需的,因为fillIn
方法永远不会以多态方式调用。这只是文档,真的。
我认为填写过程非常简单。显然,它可能更复杂,无论是在检测填充的内容(例如,空的学生列表可能表明列表尚未填充),以及如何填写它。如果您将此设计应用于您的真正的问题,你会发现DataCollector
变得异常复杂。你需要以不同的方式考虑它;您可能希望将更多的集合逻辑移动到域类中,或者将其拆分为每类DAO(ClassRoomInfoDataCollector
等)。
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) {
...
}
}
答案 2 :(得分:0)
尝试“立面设计模式”。希望它可以帮到你。你可以在http://javapapers.com/design-patterns/facade-design-pattern/
找到关于Facade的好描述