繁体   English   中英

良好的设计模式,用于收集复杂对象中的数据

[英]Good design pattern to collect data in a complex object

让我们说,我有一个复杂的对象层次结构,如:

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

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

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

我认为在需要时你需要延迟加载数据ClassRoom类成员的getter应该足以满足这个目的。

建议不要使用单独的DataCollector类,因为它会强制您在ClassRoom为所有成员公开setter。

链接 (和Book)应该告诉您有关延迟加载的更多信息。

这是一种方法。 我们的想法是将ClassRoom视为复合模式的一个实例,其中层次结构中的每个对象都知道如何使用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) {
        ...
    }
}

尝试“立面设计模式”。 希望它可以帮到你。 你可以在http://javapapers.com/design-patterns/facade-design-pattern/找到关于Facade的好描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM