Description
Hi, I've implemented part of my own framework in ddd way. As for entity model, many said it's better to use rich domain model (In contrast to anemic model) , which means the biz entity model should have biz method.
Here I have a specific question on this simple use case:
@attrs(auto_attribs=True, kw_only=True)
class MallCartModel(BaseEntityModel):
user_id: int
line_items: List[OfficeMallCartLineItemModel] = Factory(list) # line item collection mapped as one to many relationship
def add_line_item(self, sku_id, quantity):
line_item = next((one for one in self.line_items if one.sku_id == sku_id), None)
if line_item:
line_item.quantity += quantity
else:
self.line_items.append(OfficeMallCartLineItemModel(sku_id=sku_id, quantity=quantity, cart_id=self.id))
Here we have a cart model, which belongs to a user (by user_id), and some product line items.
A simple use case is: add sku item to cart, if the sku exists, just increase quantity, else add the sku line item into line_items collection.
The cart is an aggregation root, with line_items (list of OfficeMallCartLineItemModel) is composed as part of the aggregation.
After mapping these models with relationship, we can do OOP operation just like looping list in memory. So I have a model method 'add_line_item'.
But I noticed if do it like this, the loop on list actually cause sqlalchemy triggering sql select per item, here I have some concerns:
- just use this code, but if cart contains too many of line items, a lot of sql select will be triggered, even lead to N+1 query problem in some cases;
- as above, if we eager load the items to memory, it seems we must keep in mind the line items is not a huge collection otherwise we will short of memory;
- If we use sqlalchemy session query filter instead of "looping list like OOP", the model becomes dependent on repository (which do the db query stuff);
So finally I turned to another approach,make the add_line_item as one of the methods of cart repository but not of cart model. The model seems like an anemic model.
Any idea on this kind of question?