Skip to content

A question about rich domain model which may not mentioned in book #315

Open
@Bryant-Yang

Description

@Bryant-Yang

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:

  1. 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;
  2. 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;
  3. 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions