2

假设我有一个复杂的对象层次结构,例如:

public class ClassRoom
{
    private ClassRoomInfo classRoomInfo;
    private List<Student> students;
    ...
}

我将此对象作为来自客户端的输入,但该对象可能未完全填充。例如,客户端可以提供非常少的细节,例如对象studentId(s)中的次要信息。classRoomInfo我想DataCollector为这个对象编写一个类,它将预先收集所有丢失的数据。

在这种情况下,最好的设计模式是什么?

4

3 回答 3

2

这是一种方法。这个想法是将视为复合模式ClassRoom的一个实例,其中层次结构中的每个对象都知道如何使用. 如果一个对象已经被填充,它会通过返回自身来响应被要求填充自己的请求;如果未填写,它将从使用不可变对象来表示数据)。DataCollectorDataCollector

我已经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) {
        ...
    }
}
于 2013-01-30T18:22:53.837 回答
2

我认为您需要在需要时延迟加载数据。类成员的 getterClassRoom应该足以满足此目的。

不建议使用单独的DataCollector类,因为它会迫使您ClassRoom为所有成员公开设置器。

这个链接(和书)应该告诉你更多关于 Lazy load 的信息。

于 2013-01-30T09:32:49.397 回答
0

尝试“外观设计模式”。希望它可以帮助你。您可以在http://javapapers.com/design-patterns/facade-design-pattern/中找到有关 Facade 的良好描述

于 2013-01-30T07:11:47.333 回答