簡體   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