Thanks for looking into this!
First of all, there is not a single approach suitable for all cases where
this bad assumption currently resides. Also keep in mind it is not just
claims. The only thing each type of entity will have for certain is an ID
and a type.
The kind of interface you need really depends on the user. Sometimes you
might be fine with just a list of claims or a Fingerprint object. Sometimes
you might need that and an EntityId. Perhaps you need more. If the
parameter list gets long, or some combination is often repeated and turns
out to be a concept in our domain, creating a new aggregate for it is
probably a good idea.
There are cases where you inherently get "an entity" and need to handle it,
including behaviour specific to the type. At such places it is often good
to have dedicated handlers, and these handlers might indeed have some
duplication in them. A good example of this is the entity diffing code
which I refactored in DataModel 1.0, and for which the EntityDocument
interface was introduced.
Note how this object delegates to one of the registered strategies. Such a
pattern can be used instead of the often hardcoded handling in
Wikibase.git, which prevents addition of new entity types by other
extensions. If you look at the individual classes, you will see they are
There is little duplication though. Just the 3 lines for aliases, labels
and descriptions. If that code was more significant, you could create an
object to handle it, and use composition. While the rest of the class is
still similar, trying to mash this together via inheritance will just lead
to increased complexity and loss of flexibility. The wrong abstraction
tends to be much more costly then some duplication, and definitely than
some similar code.
Jeroen De Dauw - http://www.bn2vs.com
Software craftsmanship advocate
Evil software architect at Wikimedia Germany