2

たとえば、次のような複雑なオブジェクト階層があるとします。

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

このオブジェクトをクライアントからの入力として取得しましたが、オブジェクトが完全に満たされていない可能性があります。たとえば、クライアントはstudentId(s)、オブジェクト内の情報やマイナーな情報など、非常に最小限の詳細を提供できclassRoomInfoます。DataCollector不足しているすべてのデータを事前に収集する、このオブジェクトのクラスを作成したいと考えています。

この場合、どのような設計パターンが最適でしょうか?

4

3 に答える 3

2

必要に応じてデータを遅延ロードする必要があると思いますClassRoom。この目的には、クラスのメンバーのゲッターで十分です。

個別のクラスは、すべてのメンバーのDataCollectorセッターを公開する必要があるため、お勧めしません。ClassRoom

このリンク(およびブック)は、遅延読み込みについて詳しく説明しているはずです。

于 2013-01-30T09:32:49.397 に答える
2

これが1つのアプローチです。を複合パターンClassRoomのインスタンスとして扱い、階層内のすべてのオブジェクトが. オブジェクトがすでに入力されている場合、それ自体を返すことによって、それ自体を入力するように求められることに応答します。入力されていない場合は、から必要な情報を取得し、入力された独自のクラスの新しいインスタンスを構築します (したがって、オブジェクト自体は不変です。オブジェクト自体を変更することを好むかもしれませんが、私は通常、不変オブジェクトを使用してデータを表す)。DataCollectorDataCollector

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) {
        ...
    }
}
于 2013-01-30T18:22:53.837 に答える
0

「ファサードデザインパターン」をお試しください。それがあなたを助けることを願っています。http://javapapers.com/design-patterns/facade-design-pattern/で Facade に関する適切な説明を見つけることができます。

于 2013-01-30T07:11:47.333 に答える