开发者

Object composition references -- bidirectional?

开发者 https://www.devze.com 2023-02-17 01:28 出处:网络
Let\'s say you have a class object:开发者_JAVA技巧 public class Class { IList<Student> students;

Let's say you have a class object:开发者_JAVA技巧

public class Class
{
    IList<Student> students;
}

And you have a student object:

public class Student
{
    private Class class;
}

When loading these objects from the database, what is the best way to load the association?

When you load a class, you will have an empty list of students. If you load students first, you will have a null reference to the class object until the classes are loaded.


When loading these objects from the database, what is the best way to load the association?

If you're using an ORM, just let the lazy loading feature handle it. Just be aware of the select n + 1 problem.

If you're not using an ORM, start using an ORM.


This is one of those problems that I wrestle with all the time. The most elegant approach that I've come up with (so far) is to simply create properties for the objects that handle all this for me.

Ultimately it comes down to what situations you're using these classes in. For example in a gradebook application you'd drill-down through classes and into the student records. On the other hand, if you're doing a class registration application you'd have students that you add to classes, and drill down from the students into the classes they have registered to.

Since we have no real scope of the application you're discussing, lets just roll generic style, shall we? Here's a class' classic Class class. (Ahh, that was fun.) The same ideas would apply to the Student class, however.

public class Class
{
    IList<Student> _students;
    public IList<Student> Students
    {
        get
        {
            if(_students == null)
            {
                _students = new IList<Student>();
                PopulateStudents(); // just for simplicity
            }
        }
        // no need for a setter usually... Use Students.Add(Student s)
    }
}

What this allows you to do is on-demand loading of the students for this particular class. Supposing this is for web development, if your application is looking at information about a class, but doesn't need the list of students right now, why pull it from the database? PopulateStudents() can be as complex as you like. At minimum you'll put the database calls in there, but it wouldn't be a bad idea to throw some caching in there as well.

If you do it properly, you won't really have to worry about what order you load the objects. They all get loaded when you want/need them, and require no thought on your part in your consumption code. When you call

Class c = new Class(id); // You do need a class to get its students...
IList<Students> studentList = c.Students;

You don't really know if your data was already pulled, or still needs to be pulled, or what - and what do you care? Let the class itself handle the gritty details.

Naturally there are considerations to make that you need to work out. For example, what about the 'new' Class (in other words, the class that isn't in the database yet). With some thorough programming, however, the end result is the same.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号