Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Bryant-Yang opened this issue Dec 21, 2020 · 2 comments
Open

Comments

@Bryant-Yang
Copy link

Bryant-Yang commented Dec 21, 2020

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?

@hjwp
Copy link
Contributor

hjwp commented Dec 29, 2020

I guess I'd opt for either 1) or 2) depending on the specific circumstances?

I've not come across the idea of a "congestion model" by the way -- do you know where i could read about it?

@Bryant-Yang
Copy link
Author

Bryant-Yang commented Dec 30, 2020

sorry for the misuse of word 'congestion', I just translate it from Chinese literally. It should be called rich domain model.

@Bryant-Yang Bryant-Yang changed the title A question about “congestion model” which may not mentioned in book A question about rich domain model which may not mentioned in book Dec 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants