Inheritance and Event Sourcing

708 views
Skip to first unread message

Eric Quist

unread,
Feb 6, 2011, 7:46:41 PM2/6/11
to DDD/CQRS
I'm new to this, so it seems like I get stuck on things all the time.
All help is much appreciated.

My domain is about reporting time, and time is reported by a person on
a project. There a different kinds of projects; customer project,
built-in projects and non-attendance projects (the last one is also
considered to be built-in projects). My initial idea on how to solve
this would be to have an inheritance hierarchy here. First an abstract
project which built-in project and customer project inherits from and
then letting the non-attendance project inherit from built-in project.
In back of my head I hear echoes of Greg mentioning in his video that
he almost does not use inheritance anymore. I am familiar with that
composition is generally preferred over inheritance, and when looking
into sample code of event sourcing (for example ncqrs and Greg’s
SimpleCQRS) none of them have built-in support for getting aggregates
which is of different types. The project is the aggregate root, so
even if not using inheritance, I don’t know what type a specific Id
is.

A similar case is that I have companies, which could be an internal
company for the organization using the software, or an external
company. Both types are customers to projects, but there are
requirements to be able to do follow up differently on internal
projects (projects having a company from inside the organization)
compared to external projects. (There are other things in the domain
too that depends on this, not just reporting.)

Are you using inheritance in your CQRS/Event Sourcing domains? (I
guess not)
What alternatives have you used? (I guess composition, but don't know
exactly how)

I have an idea about having three interfaces exposing different
functionality for the three project types. But how should the
consuming code know to which interface to cast for a specific Id?

A concrete example is that customer projects should have the
possibility to add activities, and not the other two. How would you
solve this? An exposed composition that returns null for all, but
customer projects?

I would be grateful for some code examples.
/Eric

Elliott O'Hara

unread,
Feb 6, 2011, 8:30:45 PM2/6/11
to ddd...@googlegroups.com
Almost every time someone says "inheritance" it's because they're
thinking about the shape of data instead of what something does. Make
your AR's encapsulate parts of behavior, and not "chunks of data".

Adding Activity is a certain part of behavior, the fact that it can be
done to other things does not mean that you should inherit some the
other thing. That just gets you tighter coupling and make things more
difficult to change. Udi has a very great blog on this
-http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/.

Why couple up Adding Activity to the Customer Project object? What
does that buy you?

The only thing it buys you is read concerns, and in CQRS you've got
that separate :)

Explain the domain a little more to us, betcha you'll get some great
input if you give us a few more examples.

/E

Eric Quist

unread,
Feb 7, 2011, 3:44:11 AM2/7/11
to DDD/CQRS
I know that inheritance makes things harder to change, so I wanted to
get your experience on the alternatives :)

I would definitely say that activity (and project member) is part of
the project aggregate. They share the same life cycle, aka part of the
same transaction and that is a natural boundary in my domain. The
domain is not used for project planning or anything like that, so the
activities here are more about controlling time reporting according to
the deal with the customer. For example, if we have a custom
development project, the customer might want to see times spent on
project administration, meetings, documentation, codeing and
requirements. Those would then be activities on that customer project.
They are not just used for reading, we for example want to check that
the user only have reported time on the activities defined for that
project.

/Eric
> > /Eric- Dölj citerad text -
>
> - Visa citerad text -

@seagile

unread,
Feb 7, 2011, 6:26:42 AM2/7/11
to DDD/CQRS
I'd be very careful with using inheritance for conditional behavior
sharing and expected semantics (http://en.wikipedia.org/wiki/
Liskov_substitution_principle).
I might be wrong here, but I think you need roles and ditch the whole
inheritance thing: http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan

Elliott O'Hara

unread,
Feb 7, 2011, 8:14:21 AM2/7/11
to ddd...@googlegroups.com
What I do in a scenario like your describing is make an interface for
that behavior.

IActivityContainer (or something)
AddActivity(whatever)

I then mark whatever AR implements it.

AddActivity command handler just depends on a IRepository<IActivityContainer>

void Handle(ActivityAddedToProject @event)
{
_activityContainerRepository(@event.ProjectId).AddProject(@event.SomeProperty);
}

Works great for me.

Eric Quist

unread,
Feb 7, 2011, 10:41:49 AM2/7/11
to DDD/CQRS
I looked through the video and it is good, but there is still
something that don't click for me. I am thinking about having
something like making the roles specific, but I can't seem to get it
together. I'll try som code directly written here.

class Project : ICustomerProject, IBuiltInProject,
INonAttendanceProject
{
}

Say that AddActivity is declared on ICustomerProject. An application
service asking the repository for a project will be able to:

ICustomerProject proj =
(ICustomerProject)repository.GetById<Project>();
proj.AddActivity()

In AddActivity I need to make sure that the project actually is a
customer project. How could this be done ... an easy way is to check a
variable of course, but that feels like a smell. An alternative is to
have some Value Object exposed on the project that is null for built-
in and non attendance projects, but initialized for customer projects
and then have the AddActivity on that value object. But if I have
understod things correctly, when using ddd we want to have the
behavior exposed on the aggregate root? (Rember, I'm a beginner on
this)

Also, when reporting Time (resides on Person today, because the
requirements is that it is possible to report time without specifying
a project) I want to know if it is a customer project or a built-in
project because for buil-in projects the state of the Time object is
moved forward, but not for customer projects.

So here is two examples where my logic needs to know what kind of
project I'm dealing with and I can't get the pieces together into a
good solution.

Thanks, Eric

Eric Quist

unread,
Feb 7, 2011, 10:45:50 AM2/7/11
to DDD/CQRS
It is probably me not understanding, but ...

I have a hard time to see, why Activity would belong to any other
aggregate than Project (it should be in the same transaction), and
then I don't have a repository for activity either.
In my mind it is also a little bit turned around with adding the
project on the activity. One activity only belongs to one project and
is not reused on other projects. So, if I don't care about built-in
projects and non attendance projects, I would definetly have added the
activity to the project with just a Project.AddActivity()

Thanks, Eric

On 7 Feb, 14:14, "Elliott O'Hara" <elliott.oh...@gmail.com> wrote:
> What I do in a scenario like your describing is make an interface for
> that behavior.
>
> IActivityContainer (or something)
> AddActivity(whatever)
>
> I then mark whatever AR implements it.
>
> AddActivity command handler just depends on a IRepository<IActivityContainer>
>
> void Handle(ActivityAddedToProject @event)
> {
>    _activityContainerRepository(@event.ProjectId).AddProject(@event.SomeProper­ty);

Elliott O'Hara

unread,
Feb 7, 2011, 11:08:33 AM2/7/11
to ddd...@googlegroups.com
:)
CustomerProject is thinking about the shape of the data. Let's talk
about specific behavior.

Certain (for now only one) types of projects have activities. The
system doesn't doesn't need to care that it's a "customer" project,
just that it's a project that you can add activities too, right?

Think about the commands you'll need to add activities, you'd never be
doing anything besides just adding the activity, so just build a
Repository<IActivityProject>

For now, it's totally fine if it just returns a Customer project, but
consuming code won't even know it's a Customer project, it'll just
know it's an IActivityProject

I'm not an ES guru, but I do this thing in NHibernate all the time.

_session.Query<IActivityProject>().First(p => p.Id == theId) would get
you ANY object that implemented IActivityProject.

I'd be very surprised if the ES tools didn't support the same thing.

Once again, the process of getting your thinking "behavior centric"
can be daunting. We've had this "data first" stuff shoved in our head
for years.... But I make it a point now to avoid writing persistence
code until the last minute, it's very liberating :)

Does that make sense?

Elliot Ritchie

unread,
Feb 7, 2011, 12:23:11 PM2/7/11
to DDD/CQRS
You can hydrate different objects off the same event stream. This
allows you to explicitly model different behaviours within your system
using objects that share an identifier.

E.g. BuiltInProject and NonAttendanceProject are separate objects that
expose different behaviour but they can share the same ID and can be
hydrated from the same event stream. You will know what specific type
you need your repository to instantiate for you based on the type of
command that your are processing.

Elliott O'Hara

unread,
Feb 7, 2011, 12:29:56 PM2/7/11
to ddd...@googlegroups.com
+1 To what the other Elliot said :)

Nuno Lopes

unread,
Feb 7, 2011, 2:41:08 PM2/7/11
to ddd...@googlegroups.com

Hi,

>> My domain is about reporting time, and time is reported by a person on
>> a project. There a different kinds of projects; customer project,
>> built-in projects and non-attendance projects (the last one is also
>> considered to be built-in projects).


There are several ways to get around inheritance. Composition is one of them.

You can also use the State Pattern: Have a look at: http://en.wikipedia.org/wiki/State_pattern

Class Project {
ProjectType _pType;
.....

Project(..., ProjectType pType) -> ....

F1(...) -> _pType.F1(this, ....);
Fn(...) -> _pType.Fn(this, ....);
}

You can also inject behaviour based on intent.

Class Project<Scenario> {
Scenario _pScene;
.....

Project(..., Scenario pType) -> ....

F1(...) -> _pScene(this, ....);
Fn(...) -> _pScene(this, ....);
}

Project< Scenario> p = Projects.Get<Scenario>(x, SomeScenario);

This is a variant of the state pattern where the behavioral state is defines by the use case.

Hope it helps,

Cheers,

Nuno

Nuno Lopes

unread,
Feb 7, 2011, 2:46:45 PM2/7/11
to ddd...@googlegroups.com
I should also note that State Pattern can be miss used. If you start getting too many fake methods just to fit in the interface gap probably you should use composition. Or better still split the Aggregate in multiple Aggregates more specific to the use case.

Cheers,

Nuno

Eric Quist

unread,
Feb 7, 2011, 6:20:41 PM2/7/11
to DDD/CQRS
I don't understand why I would know the specific type from the
command? Take for example the ReportTimeCommand, which will have a
ProjectId (just the Guid) for the project.

An alternative would of course be to have
ReportTimeForCustomerProjectCommand,
ReportTimeForNonAttendanceProjectCommand and so on. Is that what you
suggest?

Thanks, Eric

Elliott O'Hara

unread,
Feb 7, 2011, 8:22:20 PM2/7/11
to ddd...@googlegroups.com
You don't care about the specific type.  Not at all, not one little bit :)
I agree with Nuno, that a separate AR is probably the right way to go in this scenario, but for the sake of discussion, lets talk about how to do this with composition.


public interface IReportable{
  void ReportTime(int hours);
}


public class ReportTimeCommandHandler:ICommandHandler<ReportTime>
{
 ReportTimeCommandHandler(IReporitory<IReportable> repository){
    _repo = repo;
}
 public void Handle(ReportTimeCommand cmd){

   _repo.GetById(cmd.ProjectId).ReportTime(cmd.hours);
}
}


DONE!!! :)

ORM or ES, both can easily return the correct concrete type for IReportable, but that concrete command does not matter. All you care about is that the thing you get back from the repo can report time.

Encapsulate the behavior, not the data.

I hope that helps :)

Nuno Lopes

unread,
Feb 8, 2011, 4:09:29 AM2/8/11
to ddd...@googlegroups.com

The project is the aggregate root, so
even if not using inheritance, I don’t know what type a specific Id
is.

Using the state pattern you only need to know what type the project is when it is created.

From then on the type is persisted and the defined behavior should be injected upon rehydratation. 

In other words, the caller does not need to know what type the Project is as much as it does not need to know the state of of the project. 

Does this make sense?

Nuno 

Sent from my iPad

Eric Quist

unread,
Feb 8, 2011, 9:39:53 AM2/8/11
to DDD/CQRS
The samples I've seen (and I think this is also true for the built-in
support in nCQRS) only have simple object creation strategies (aka new
T()) which won't work with an interface. I can see this beeing solved
with a IOC framework of choice though, so it will be able to get
support for a system where roles are made explicit.

The Time entity is of course an aggregate root.
What I don't understand is why Activity would be better as an
aggregate root of its own. For me that is like saying that all
entities should be realised as Aggregates. In this particular case I
have several issues:
* The activities and projects share them same life cycle. When a
project is deleted (if that would have been supported) the activities
would go too). The activities is of no intereset outside of the
project.
* When getting a project from the aggregate, I always want the
activities to be loaded since a lot of the behavior is depending on
them. (I know this could be solved with NHibernate, but when using
event sourcing I would have to do a call to GetById for each activity
in the project)
* Who should be responsible to load the activities to the project (so
it can perform its behaviors correctly)? I'm not aware of any lazy
loading support in any event store (I haven't been looking hard either
though).
* And I could continue

Thanks, Eric
> > > - Visa citerad text -- Dölj citerad text -

Eric Quist

unread,
Feb 8, 2011, 9:44:00 AM2/8/11
to DDD/CQRS
I think this is somewhat how I been thinking myself, so I think I
follow you. I am familiar with the State pattern, but I have only used
it for more classic state situations (for example an order beeing
NewOrder, GrantedOrder, Cancelled, Shiped, Invoiced).

But what you suggest is that I handle this composition in the same way
even if I don't see it as the state of the project, but that might not
be a reason to not use the pattern :). I think I can see how that
should be done, and I might try this.

Thanks, Eric

On 8 Feb, 10:09, Nuno Lopes <nbplo...@gmail.com> wrote:
> >> The project is the aggregate root, so
> >> even if not using inheritance, I don’t know what type a specific Id
> >> is.
>
> Using the state pattern you only need to know what type the project is when it is created.
>
> From then on the type is persisted and the defined behavior should be injected upon rehydratation.
>
> In other words, the caller does not need to know what type the Project is as much as it does not need to know the state of of the project.
>
> Does this make sense?
>
> Nuno
>
> Sent from my iPad
>
> > > - Visa citerad text -- Dölj citerad text -

√iktor Klang

unread,
Feb 8, 2011, 11:09:18 AM2/8/11
to ddd...@googlegroups.com
On Tue, Feb 8, 2011 at 3:39 PM, Eric Quist <equ...@hotmail.com> wrote:
The samples I've seen (and I think this is also true for the built-in
support in nCQRS) only have simple object creation strategies (aka new
T()) which won't work with an interface. I can see this beeing solved
with a IOC framework of choice though, so it will be able to get
support for a system where roles are made explicit.

The Time entity is of course an aggregate root.
What I don't understand is why Activity would be better as an
aggregate root of its own. For me that is like saying that all
entities should be realised as Aggregates. In this particular case I
have several issues:
* The activities and projects share them same life cycle. When a
project is deleted (if that would have been supported) the activities
would go too). The activities is of no intereset outside of the
project.
* When getting a project from the aggregate, I always want the
activities to be loaded since a lot of the behavior is depending on
them. (I know this could be solved with NHibernate, but when using
event sourcing I would have to do a call to GetById for each activity
in the project)
* Who should be responsible to load the activities to the project (so
it can perform its behaviors correctly)? I'm not aware of any lazy
loading support in any event store (I haven't been looking hard either
though).

That would mean that you do not process the event log for the AR in full, since you're deferring the processing of Events of certain entities until they are "needed", which either means that you need to do extra loads or keep the events in memory.
 



--
Viktor Klang,
Code Connoisseur
Work:   Scalable Solutions
Code:   github.com/viktorklang
Follow: twitter.com/viktorklang
Read:   klangism.tumblr.com

Eric Quist

unread,
Feb 8, 2011, 1:18:05 PM2/8/11
to DDD/CQRS
I'm not sure I understand. Who will keep the events in memory if
Activity is made to an aggregate instead of being included in the
Project aggregate?
> Work:   Scalable Solutions <http://www.scalablesolutions.se>
> Code:   github.com/viktorklang
> Follow: twitter.com/viktorklang
> Read:   klangism.tumblr.com- Dölj citerad text -

Nuno Lopes

unread,
Feb 8, 2011, 2:16:28 PM2/8/11
to ddd...@googlegroups.com
Hi,

> What I don't understand is why Activity would be better as an Aggregate

Neither it is :)

You are quite right, if your axis of behavioral change is to the Project Type. That is the same axis of change as the traditional OO class inheritance.

The problem of OO class inheritance is that it only encapsulates behavioral distinction downwards. We need to keep in mind that inheritance is about abstractions, not so much adding new features to existing ones.

So class inheritance is limited. Even more limited in OO languages that don't support multiple inheritance. But if it fits the bill for your particular problem I would use it.

What people have found is that are other more fine grained Axis of behavioral change as for instance the Role of an object in a particular activity. They find it more useful then go for class inheritance.

http://www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/extension-objects-gamma.ps

Extention Objects are not so much about abstraction as they are with context/feature/activity. This is not a replacement of OO class inheritance, but one that people find more useful.

To this you need to see a Class has a collection of features. Now you have your multiple project types correct? What kind of features they have in common and what kind of features each type of project has different?

So say F1 is common to all, and F2 is specific to one.

So when you do:

F1 f = AllProjects.get<F1>(projectId);
f.execute(...);

It does not really matter if is a project of type A, B, or C that implements its, as long as it implements it. In this case they all do because it is common to all of them.

F2 f = AllProjects.get<F2>(projectId);
f.execute(...);

Would result in an exception if the project does not implement that feature.

If the project whose id is given does not support the given feature, the query should return an exception.

So far so good right? Simple?

Now let's focus on the event stream for a moment. An event stream is a Bag of facts. Let's say we have a Bag of facts about all projects. Each fact as encoded the type of its subjects (Say the type of project)

Now we know that we can correlate the type of project with a Class. StandardProject, CustomerProject etc etc. If can have a mechanism that based on the type of project and a class correlation rule is able to rehydratate any of object of these classes we have a clever way to to get the objects.

Now here is the drill. We are not interested in the object themselves so much as we are interested in what they represent (Project) and their features (F1, F2, ....);

So the client never deals with ProjectA, ProjectB ... etc. It deals with F1, F2, ..., FN of a specific entity (project id); Remember as long as specific project implements a feature there is no exception.

For this to work, you would to think that one single Entity can have multiple implementations, as much as the features.

So you would need to think that we have an abstract concept called Project, one entity, one aggregate to which we add a variable set of features.

Have a look at http://www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/extension-objects-gamma.ps;

When we call: F1 f = AllProjects.get<F1>(projectId);

We are getting an Object Extention (F1) of generic concept we call Project whose specific implementation is unknown to the client (ProjectA, ProjectB, ProjectC ....);

The downside, is that the client can longer is casting because what we don't know its type of Class neither does it car. Every Time we want a different feature we need to go to AllProjects. (We call this a Repository in DDD, but in OO terms used to be called a Object Extent, the collection of all objects of a given type).

F1 f1 = AllProjects.get<F1>(projectId);
f1.execute(...);

F2 f2 = AllProjects.Cast<F2>(f);
f2.execute(...);

Powerfull no?

As usual different tools for different trades.

Nuno Lopes

unread,
Feb 8, 2011, 2:45:40 PM2/8/11
to ddd...@googlegroups.com

... And now Eric I will blow your mind (lollol, don't worry it has blown mine when I discovered this by myself, but I'm sure others have).

Software is an every evolved activity right? Our concepts change often. For instance, features will be added to ProjectA, other features will be changed etc etc.

Quite often when we change a Class we produce a new dll and deploy. We need to change the data schema of the say your relational database, some transformations etc. The same goes with the event stream? ... not quite :)

Event if you change an type of event, you don't need to change all records of given event. Indeed you should not.

Remember I wrote:

> Now let's focus on the event stream for a moment. An event stream is a Bag of facts. Let's say we have a Bag of facts about all projects. Each fact as encoded the type of its subjects (Say the type of project)


The type of project is important for rehydration purposes but not only. This type can be the type of the implementation class to be rehydrated not some random description. If you do that ...

Suppose that we change a given say feature F1 (each feature results in an event). We may even change the feature so much that we probably need to add or remove subjects from the event (FIELDS).

Now say that instead of changing implementation class ProjectA we create a new one ProjectAChanged.

Now say that when we now create a project of type A instead of using ProjectA implementation we use ProjectAChanged implementation from then on.

Voila instant system upgrade with no down time. New projects will use ProjectAChanged implementation while old ones will proceed as usual :). An they all share the same event stream ... Project.

Cheers,

Nuno

Eric Quist

unread,
Feb 8, 2011, 3:44:36 PM2/8/11
to DDD/CQRS
I understand that I will be more flexibel without inheritance, and I
thought I expressed that I don't wanted to use inheritance in my
original question (but after re-reading it, I understand that I
wasn't).

Anyway, I see two options if I understand your answers fully.

a) One is to only have one Project class, which could be created by
calling one of the following static functions
CreateNewCustomerProject, CreateNewBuiltInProject and
CreateNewNonAttendanceProject. In respective method I would
instantiate the child classes suitable for respective project type (as
in the state pattern).

b) The second approach (which is what I believe you describe in your
latest post) is that I will have three classes CustomerProject,
BuiltInProject and CreateNewNonAttendanceProject. Each class will make
its roles explicit by implementing interfaces describing each role
(F1). When asking the repository, I will ask for a class with a role
(F1): AllProjects.get<F1>(projectId). In this case I can't let a IOC
tool determine which class to instantiate, since F1 could be
implemented by all three project classes. Instead the EventStore is
required to store information about what type the class with the
specific Id is.

Du you know if any of existing event store implementations (nCQRS,
Jonathan Oliver's) support storing the type of its subject and
rehydratate it? Greg's document (http://cqrsinfo.com/documents/
building-event-storage/) describing an implementation of an event
store does not seem to cover this type of functionallity.

I don't see any problem of having to ask the repository again.
Normally one command is only interested in one feature to run on the
object I guess?


I have never opened a postscript file (.ps) before. Do you recommend
any special program to do it? GSview (http://pages.cs.wisc.edu/~ghost/
gsview/get49.htm)?


On 8 Feb, 20:16, Nuno Lopes <nbplo...@gmail.com> wrote:
> Hi,
>
> > What I don't understand is why Activity would be better as an Aggregate
>
> Neither it is :)
>
> You are quite right, if your axis of behavioral change is to the Project Type. That is the same axis of change as the traditional OO class inheritance.
>
> The problem of OO class inheritance is that it only encapsulates behavioral distinction downwards. We need to keep in mind that inheritance is about abstractions, not so much adding new features to existing ones.
>
> So class inheritance is limited. Even more limited in OO languages that don't support multiple inheritance. But if it fits the bill for your particular problem I would use it.
>
> What people have found is that are other more fine grained Axis of behavioral change as for instance the Role of an object in a particular activity. They find it more useful then go for class inheritance.
>
> http://www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usa...
>
> Extention Objects are not so much about abstraction as they are with context/feature/activity. This is not a replacement of OO class inheritance, but one that people find more useful.
>
> To this you need to see a Class has a collection of features. Now you have your multiple project types correct? What kind of features they have in common and what kind of features each type of project has different?
>
> So say F1 is common to all, and F2 is specific to one.
>
> So when you do:
>
> F1 f = AllProjects.get<F1>(projectId);
> f.execute(...);
>
> It does not really matter if is a project of type A, B, or C that implements its, as long as it implements it. In this case they all do because it is common to all of them.
>
> F2 f = AllProjects.get<F2>(projectId);
> f.execute(...);
>
> Would result in an exception if the project does not implement that feature.
>
> If the project whose id is given does not support the given feature, the query should return an exception.
>
> So far so good right? Simple?
>
> Now let's focus on the event stream for a moment. An event stream is a Bag of facts. Let's say we have a Bag of facts about all projects. Each fact as encoded the type of its subjects (Say the type of project)
>
> Now we know that we can correlate the type of project with a Class. StandardProject, CustomerProject etc etc. If can have a mechanism that based on the type of project and a class correlation rule is able to rehydratate any of object of these classes we have a clever way to to get the objects.
>
> Now here is the drill. We are not interested in the object themselves so much as we are interested in what they represent (Project) and their features (F1, F2, ....);
>
> So the client never deals with ProjectA, ProjectB ... etc. It deals with F1, F2, ..., FN of a specific entity (project id); Remember as long as specific project implements a feature there is no exception.
>
> For this to work, you would to think that one single Entity can have multiple implementations, as much as the features.
>
> So you would need to think that we have an abstract concept called Project, one entity, one aggregate to which we add a variable set of features.
>
> Have a look athttp://www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usa...

Elliott O'Hara

unread,
Feb 8, 2011, 4:06:18 PM2/8/11
to ddd...@googlegroups.com
Nuno,
Great work man... very well written!
Reply all
Reply to author
Forward
0 new messages