In my DDD attempt I've defined the following ubiquitous language:
A product can have multiple drawings. A drawing consists of a drawing number, a revision number* and multiple attachments**. A drawing can be revised by a new drawing with a different revision number.
Invariants:
- for every drawing number a product has, there can only be one current revision.
- there can be no drawings with the same drawing number and revision
*sometimes initially empty
**the attachments are the actual product drawings, can be .jpg, .pdf, .stp, etc.
Is there a mismatch in the language? These attachments can also be called the actual drawings where the above properties are merely metadata to programmatically distinguish them.
Some context, the application should help the business with the development of products. The drawings are concepts that after discussion and revisions will form a sample that must be approved by the customer. For this context, I've chosen an event-sourcing architecture because of the business value to evaluate the incremental development of products.
The problem I'm having is whether to put these past revisions in the model. This could be done by adding a boolean property to the drawings that indicate if they are the currently used drawing. This however goes against my gut-feeling to model drawings as immutable value objects (now the drawing has a mutable property). In my mind I've supported this gut-feeling with the argument that once a drawing is changed this results in a new drawing with a different revision number.
Another gut-feeling I have though, is that I should put the past revisions in the model as they have business value. Is it a good solution to let a product have a list of current drawings and past drawings?
How should I think about when a user wants to correct a drawing? For example, when someone didn't attach all correct files to the drawing and you later want to correct this by adding more files, or removing some?
Code example
To give a brief example with some code, this is one of the things I came up with, the drawing as an value-object that uses the drawing number and revision in the equals method:
public class Product {
private Set<Drawing> currentDrawings;
private Set<Drawing> oldDrawings;
}
public class Drawing {
private String drawingNumber;
private String revision;
private Set<URL> files;
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Drawing)) return false;
Drawing other = (Drawing ) o;
if (this.drawingNumber != other.drawingNumber) return false;
if (this.revision != other.revision) return false;
return true;
}
//getters and constructor omitted for brevity
}
Not enough reputation to answer Luiz E's comment, so I'll put it here instead: in some cases a product consists of different parts, materials, and so forth. Sometimes there's a clear parent drawing that referenced other subdrawings, other times there are just a bunch of drawings of parts that will be assembled later.
I tend to adhere to the "KISS" principle, instead of modeling all these different relations between the drawings that will only confuse the users (they are not the creators of the drawings).