I have some common behaviour in several entities belonging to different aggregates, that I’d like to factor in an abstract class.
Is there any drawback to have entities in different aggregates inherit from a common abstract class?
Use case
Several entities have name, description or other properties that can be translated in different languages.
For example, I would set a name with setName(language, name) and retrieve it with getName(language).
Each text in each language is stored in an object, such as:
class EntityName
{
protected Entity entity;
protected Language language;
protected String text;
protected int version;
public EntityName(Entity entity, Language language)
{
this.entity = entity;
this.language = language;
this.version = 1;
}
// setText(), getText(), ...
}
For a given Entity class, EntityName is within the Entity aggregate. Only Entity can create, read from and write to EntityName, via setName() and getName().
However, classes such as EntityName, EntityDescription, OtherEntityName would all share pretty much the same code. The only part than changes is a reference to the aggregate, and therefore the constructor.
There isn’t much on this topic. However, have a look at this article entitled How To: Domain Driven Design
In particular, read the section entitled Step 2 – Identify Aggregates and Aggregate Roots:
If you are storing book-keeping data (id, version, create timestamp, update timestamp) that is outside the domain model proper (e.g. to support your persistence layer), I don’t see this as a problem. If, however, you are trying to reuse true business methods and attributes, you could consider replacing inheritance with composition or AOP introductions.
Update
After looking at the updated use case, it looks as though you are really trying to achieve code reuse rather than a true Liskov is-a relationship. Some languages better support this type of reuse with concepts such as mixins (Groovy) or traits (Scala). Assuming Java, one approach you could do is create a class and use Project Lombok’s @Delegate annotation to forward to your implementation. This has the following benefits:
relationship in the future
I believe this to be purer and enables flexibility in your model. I’ve used Project Lombok on a few projects with great success. It allows you to side step some of the missing language features in Java and focus more on your domain than the necessary boilerplate code required to implement certain idioms.