2

I'm learning DDD. For a practice, I'm trying to convert my own app to DDD aggregates.

What I understand so far on aggregate.

  1. Aggregate defines transactional boundary
  2. Design aggregate as small as possible
  3. If there is no invariant to protect, I might not need an aggregate.
  4. You need to load everything from an aggregate.

I have a simple example. When a user uploads an image and information on the image, my app creates products based on the image.

I have Asset aggregate and Asset has many Product entities (?)

class Asset
{
     public function newProduct(ProductType $productType) {
       // return a new Product object then save id internally
     }
}

When I add a new product to Asset, I save product id to Asset. When I load Asset from its own repository, I get a problem. Since I have more than 30+ product types, it is not optimal to load all products together. Since a Product can't exist without an Asset and a Product id must be persisted to an Asset, I have a business logic to protect.

Do I really need to load all products when I load an Asset?

Can I have a method in Asset that accepts a DAO to retrieve a product on demand? or a domain service to retrieve a product from an Asset?

class Asset
{
    public function getProduct(ProductType $productType, aDAO $dao){

    }
}

Update: Asset can't have duplicate Product

  • What are the invariants that Asset protects? – Constantin Galbenu Mar 28 '17 at 9:37
  • @ConstantinGALBENU When a user adds a new Product to an Asset, Asset must have an ID of the Product. They can't be out of sync. That's all I can think of at this time. – Moon Mar 28 '17 at 9:39
  • This is not a real invariant. Why do Asset need the product ID? – Constantin Galbenu Mar 28 '17 at 9:40
  • @ConstantinGALBENU Asset acts as a parent class for Product. When I save a Product, it does not have all the information. Product objects retrieve data from its parent Asset. In other words, I must have a parent Asset in order to load Product. And..an Asset can't have duplicate Product. I figured that's an invariant. – Moon Mar 28 '17 at 9:45
  • I suppose you don't use CQRS, do you? – Constantin Galbenu Mar 28 '17 at 9:47
2

In such situations, I'd ask myself if the business logic or model is right, not what I've implemented or what is best for software. One other thing that is important for Aggregate and DDD is ubiquitous language and implementation as business logic dictates, not what is best in software sense. So stuff like copy/paste in DDD is allowed (of course, this is a broad subject and should not be taken literary).

What puzzles me is the following sentence:

When a user uploads an image and information on the image, my app creates products based on the image.

You say that product is created based on information that are entered with the image. So, a user enters an image and some information about it and based on these information you create products. As I understood, Asset is not based on products but on informations contained in images. Also, I don't really think that products don't share the same information or images. Therefore it's more of a many to many relation based on information and, probably, information can be interconnected with multiple images.

Like you said, aggregates define transactional boundary. In that case you can ask yourself a business logic question (irrelevant of how you've implemented it)

If I delete an Asset, MUST all related products be deleted as well? Are these products independent from other Entities?

If the answer is yes, ask yourself if the model is right, have you really implemented the model according to business logic. Go to the roots, the business logic defined by domain expert and business folks, not what is currently implemented.

  • The answer is Yes and that is exactly what business logic should be. Product depends on Asset, not the other way around. – Moon Mar 28 '17 at 13:52
  • @Moon - Can the products depend on other Assets as well? What is with these Information about the Images that you talk about? How do they fit in the entire picture? – civan Mar 28 '17 at 14:23
  • Have you seen a website where they create a tshirt when you upload an image? It's basically the same idea, except that my app let you create more than t-shirt. There are over 30+ products. You can create 30+ products with a single image. That said, those 30+ products use the same title, description, and tags from Asset since they are based on the image in the Asset. An image uploader may disable/enable a product from an Asset. – Moon Mar 28 '17 at 20:30
  • If products are truly unique to an Asset, that they are transactionally related, that an Asset doesn't make sense without its Products, then, unfortunately, I can only say that you have to load them all. I don't know any other trick. Sorry :(... – civan Mar 29 '17 at 14:38
  • // No need to be sorry. Thank you for your questions. I had to ask myself again to make sure. – Moon Mar 30 '17 at 0:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.