Hey,
On 2010-11-18 01.31, Marc Grue wrote:
When we get @Concerns on POJOs (before christmas?), wouldn't we be
able to improve the context stacking intuitiveness with something as
simple like this?:
@Query public Integer availableFunds() { return
sourceAccount.availableFunds(); }
@Command public void transfer( final Integer amount ) throws
IllegalArgumentException { sourceAccount.transfer( amount ); }
Nah, it would just be like this:
public Integer availableFunds() { return
sourceAccount.availableFunds(); }
public void transfer( final Integer amount ) throws
IllegalArgumentException { sourceAccount.transfer( amount ); }
--
for the simple reason that we can put the concern on all methods in the
context, and it doesn't have to separate between command/query explicitly.
I'm taking this pretty literally, so I want to call the
TransferMoneyContext field "sourceAccount" instead of "source". Of
course you and I know what "source" means, but as a pedagodical
example, I think it's important to convey the importance of mapping
the code naming *directly* to the Use case terms. It can be a little
more tedious to write as a programmer and seem unnecessary, but I
think that the code can easily slowly start to slide into reflecting
the programmer's rather than the end users mental model of the use
case. (It's a question I want to raise in the DCI forum).
I've updated this in qi4j-sample. Typing tediousness is a non-issue
these days with autocomplete features. I rarely, if ever, type a
complete name these days.
I have saved your version without modifications as v9a, and the one
with my suggestions as v9b in qi4j_money_transfer_06.zip at
http://bit.ly/bjjjMx. My old v9a and v9b_draft are out. When I post
the new implementation model in the DCI forum, would it be okay for
you if I save v9b as a new v9, and at the same time refer to the
"official" version at github
(https://github.com/Qi4j/qi4j-samples/tree/master/dci/)? Or do you
want me to leave v9a and v9b as they are now?
You do as you see fit really. I'm keeping the qi4j-samples up to date as
we progress.
Comments to the cosmetic changes I have made in v9b:
Contexts - I think that changing method name from
Contexts.withContext(…) to Contexts.enact(…) conveys more the action
that is about to take place: the enactment.
Yes and no. With the latest version, where this is done from inside the
context, the enactment is already started. It's a minor issue though
since I expect it to go away shortly with concerns-on-objects.
ContextInjectionProviderFactory.java - Isn't it more correct to
return a *Context*InjectionProvider (instead of a
*Role*InjectionProvider)? It's the Context that we inject. I know
it's very similar to InjectionContext, but it just feels confusing to
see "Role" and "Context" mixed up here when studying how it works.
That was a copy/paste error. Fixed in qi4j-samples.
TransferMoneyTest - Expanded the logging messages to match the
logging required by the Use case algorithm. - Fluent notation of the
PayBills test, showing the 3 main steps needed to enact the use case
in one line: Context instantiation -> Role binding -> Use case
enactment The Law of Demeter shouldn't be violated by this, since
both the bind and enactment methods are defined in the same Context
that is instantiated. There are no surprises, it's fast and it can't
be more intuitive! -
In real usecases I expect this to be less relevant, as there will
typically be a difference in "time" between the bind (=selection of
objects) and enactment. In tests they appear to be close, but that's a
bit artificial. Stacked contexts, as PayBillsContext, would be the
exception though.
The "re" prefix in rebind() seems unnecessary
since in most cases where we will bind the roles for the first time.
"Re" indicates that it has happened before. Like a setter method is
not a resetter method, I suggest simply to call it "bind". We could
even have a case where only *some* roles where rebound, and the
Context role setup not entirely reset. "bind" can be used in all
cases. -
Sure, I'm ok with "bind", for reasons mentioned.
Whether Data objects are instantiated inside a context is an
implementation detail left to the programmers choice (left all
instantiation to the client as you did). Maybe there would be cases
where the Context is performing some logic to decide which Data
objects to instantiate where ids could be more suitable (but that's
another question for the DCI forum). That choice doesn't affect the
beauty of this implementation model.
Yeah, the main difference is that the context becomes dependent on
lookup method. I really like the current style where it doesn't have to
know this. It also simplifies stacked contexts I think, as the PayBills
sample shows.
TransferMoneyContext - Shouldn't the first comment be "Roles are
defined within the context, and only the *Role Maps* know about them
outside of this context"?
Fixed.
- Returned "this" from the bind method in
order to be able to have a fluent notation (as shown in second test)
I've done this too now, but as above, it's less relevant than the tests
might imply.
- Added the Use Case algorithm here also, because I want to be able
to compare the code with the text (literally!). That's also why I
added the log(output-messages) as described in the use case
algorithm.
Ok. I don't have as much logging in the sample.
PayBillsContext - Comment in creditor loop changed to "// Re-bind
Data in nested context and execute enactment" (instantiation only
happens once, before the loop)
Goodie, fixed in qi4j-samples too.
If you have any comments, I'm all ears!
I'm ready to implement the Frontloading example with the new setup!
:-)
That'll be very interesting!
Good progress!
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev