Sharing a base model is against everything that
CQRS stands for.
If your models (write and read) are 99% percent then it is a
CRUD architecture painted to look like
You must split the write from the read because the two models have different behaviors: the write model is concerned with ensuring the invariants and the read model is concerned with the reading and displaying the data to the user. It is normal that some of the fields are shared but only as concepts. In the write side, you create
Commands that have those fields, send them to the write models (
DDD) and generate
events that have some of the fields from the
commands. In the read side you read the
events and create some simple persistence objects, with no behavior that ensure the invariants; they can have behavior but a different kind from the write models.
On the read side you could have mega objects that contain fields from multiple write models. The main idea of the read models is to be very fast (i.e. no
JOINS), so you include in a
document all you need to display the data to the users.
On the other side, the write side, you put in
commands only the minimum information needed to maintain the
invariants (i.e. you refer other Aggregate roots only by their IDs).
So, as a metaphor, the write and read models are like matter and antimatter: they should not collide; they are separated (decoupled) by events that act like a magnetic fields.
The read models only see the events generated by the Aggregates (the write models); they don't query the write models as it is forbidden; so the write models have only
command methods and no
query methods; on the other hand, the read models have only
query methods (i.e.
getters) and no
command methods; the read models are immutable; the only way to
mutate the read models is by listening to the
events and apply those