I’m posting a ghost here, that daunts me for some years. It’s a question about how to build the right model, the right objects.
Let me explain. Suppose I have a class Article. An Article has title, rating, body copy and comments.
The class Comment has author, timestamp, text.
An Article can have 0 or more comments. So far, so good. No problem with this concept. But…
- When showing the Article, I show everything. Article properties, including its comments.
- When showing a list of articles, I show only article name and a few of body copy.
Here is where I got confused because I don’t need to load the comments information, and this can make a significant performance difference when I have lots of articles and tons of comments.
Should I build two models? One for Article and one for ArticlesInList? Should I delegate the load of comments to a lazy mode (is this possible), retrieving them only when necessary?
What is the right way to face and solve this?
Thx.
There are a lot of trade-offs to be made when trying to model your business objects.
Given your example, I can think of a few approaches, that mostly revolve around lazy-loading comments. Here’s how I’d do it, if I were reasonably sure that things weren’t going to get more complex:
First, you create entities for Article and Comment that simply represent the data in each table in your database. Write setters and getters. Implement a loadComments() method on Article.
Implement one or more Collection classes, such as ArticleCollection. You might have a service class that fetches articles that match some criteria. ArticleService::fetchArticles() would return articles without comments loaded. Then implement a loadComments() method of ArticleCollection that loads all the comments for all the articles in the collection. At first, this can just iterate over the articles calling loadComments — but you can replace it later with a single-query implementation.
Here’s the beginning of an Article and ArticleCollection. If you implement a CommentCollection class, you could use that inside Article to hold the comments, etc.
The above is pretty basic — you can apply other design patterns to factor out your database-access so it’s not so tightly coupled, for instance. But I’m just trying to describe a strategy for lazy-loading your comments here in a sane way.
Some final advice: Don’t fall into the trap that many framework do and think there is some divine correlation between tables in your database and models. Models are just objects. They can do different kinds of things (represent a simple thing like a comment, or a user), or represent things like a service that operates on those kinds of simple things, or they can be things like groups (collections) of those individual things.
One fun exercise is to just write up classes, and fill them up with dummy-data. Do your best to completely forget that a database will be involved. Craft objects that support the use-cases you need. Then, once you’ve got that done, figure out how to save and load the data to/from the DB.