Merry Christmas everyone, Never mind the title, but there is a design flaw in the initializable system for values. I think it stems from the fact that it was initially not very well defined and has since changed from being a callback for the Mixin rather than the Composite.
At the moment, for ValueComposites (I have not checked it to be the case for the others) the Initializable is called at vbf.newValueBuilder() after the injection phase. This is suitable for setting up things like creationTime and anything else that is not depending on what else is set from the builder. But, one can't use it to compute a property during initialization, and since properties are immutable in Value Composites, there is actually no way at the moment to do this other than in the code that instantiate the value. So, we put this (able to initialize properties during the newInstance() phase) aside as a "requirement", and let's look at a broader picture; Invariants. Long ago, we tried to solve the request that one could declare Invariant checks, especially for aggregated Entities. That effort never took root in Qi4j, and perhaps now is the time to look at the whole picture. Invariant checking is about ensuring that an Entity Aggregate is never accessible in a incoherent state. Transactions/UnitOfWork takes care of the atomicity, but there is no built-in mechanism to ensure that an invalid state has not occurred "naturally", say, the total allocated container CPU load isn't higher than the host's available CPU capacity. At the moment, such thing needs to be built in somewhere, and without front-facing services handling such entities, it is quite easy for developers to "forget" or "didn't know" such rules. The same checking mechanism should be generic enough to apply to all Composites, so let's assume that we solve this somehow. Now, such checking needs to happen in more than one place. On one hand, for entities, this needs to take place at uow.complete(), prior to committing it to persistent storage. For all composites it also needs to happen at builder.newInstance(). And for Transient Composites, it would also need to happen on every set() method. So these hook points are needed to support Invariant checks (mechanics not relevant right now), but could we make these hook points more generic, so that the initialization issue above could leverage the same underlying hook? If so, then I wonder if the majority of hooks that are in place, could be made equally generic, and therefor a big reduction in codebase handling all these hooks to be invoked. There are a great number that comes to my mind, beyond the two mentioned ones above; * Activation system * Lifecycle interface for entities * Field injection, Constructor injecton, Method injection * newValueBuilderWithState(), newValueBuilderWithPrototype(),... * newEntityBuilderWithState() * addUnitOfWorkCallback, removeUnitOfWorkCallback * StateChangeNotificationConcern And I am sure there are others. So, we could either organically add better handling of Initializable, such as adding a separate interface called during builder.newInstance(), meant for the Composite (i.e. resolved to a single mixin method call), and later figure out how to do Invariants. OR, we could tackle this head on, and figure out how such generic hook mechanism is supposed to work, and how to refactor a bunch of core functionality into pluggable parts. To me, the latter sounds like the "right" but "slow" thing to do. If it sounds reasonable to do this ( a 4.0 release in a year or so), then the next steps would be to identify all the hooks that are needed, define the mechanism and then start the refactoring. WDYAT? Cheers -- Niclas Hedhman, Software Developer http://polygene.apache.org - New Energy for Java
