I also prefer an annotation and not put boilerplate code in the domain for
ui purposes. An @AggregateRoot annotation doesn't meet all our requirements
though: we have cases where child objects are an aggregate in it's own:
Lease <- @AggregateRoot
+ LeaseItem <- aggregate for terms
+ LeaseTerm
Another approach in this case would be to use a viewer directive to ignore
the result of an action and to return to the calling page. Something like:
public class LeaseItem {
...
@Void
public LeaseTerm newTerm(...) {...}
...
}
This solution would also solve situations where you want to navigate away
from an aggregate root.
Cheers,
Jeroen
On Tue, Dec 3, 2013 at 12:48 PM, GESCONSULTOR - Óscar Bou <
[email protected]> wrote:
>
> Hi, Dan.
>
> I like a lot the idea of explicitly having an annotation for Aggregate
> Roots (and, "commercially" speaking, it can be a big call to all those
> interested on DDD...). I'm sure we will find more use cases for that
> annotation in the near future, as it will force us to consider the distinct
> semantics of ARs vs "child" Entities in different places.
>
> Also, I like also a lot the idea to have idioms that can be expressed
> through Isis templates .... but a bit unsure about imposing them (it's
> clearly not the case on what you're proposing).
>
> I assume that the "target" to evaluate would always be the entity you are
> invoking the action from.
> If it's not an AR, in theory it should be showed without being able to
> modify it (as a Value Object) in order to force the invariants imposed by
> the AR.
> Despite that, in our case, we could have contributed actions (from the AR,
> or actions from the Entity delegated to the AR) that would allow for
> properly modifying it within the context of its AR. And, if no invariants
> must be preserved on some fields, they simply could be safely edited ...
> So, basically, if properly implemented through Isis (with disabled, hidden
> and actions) a "child" entity can safely be edited preserving all
> invariants.
>
> As a derivation, on action invoked on Domain Services, Isis viewers will
> always navigate to the returned entity, despite it's an AR or not (no
> reason on DDD to return it from a Service, but no need neither to
> explicitly forbid it for those following "bad practices").
>
> HTH,
>
> Oscar
>
>
>
>
> El 03/12/2013, a las 12:21, Dan Haywood <[email protected]>
> escribió:
>
> > That's an interesting idea, Oscar.
> >
> > The issue arises from the fact that there are potentially two different
> > callers of the Order#createItem method:
> > a) the Isis framework itself - in which case, as we all know, the
> signature
> > of the methdo is used to determine presentation/navigation
> > b) other domain objects, ie programmatic interaction. In some cases the
> > caller might want the aggregate root (Order), at other times the
> aggregated
> > (OrderItem).
> >
> > Actually, being strict about (b), under DDD the aggregate root should
> never
> > return one of its constituent parts. That would argue that even for
> > programmatic interactions (b) the method should only return Order, not
> > OrderItem.
> >
> > If we relax that rule, though, then one solution is to split out the
> method
> > according to its two different callers, and have one method delegate to
> the
> > other; eg:
> >
> > public class Order {
> > public Order createItem( ... ) {
> > doCreateItem(...);
> > return this;
> > }
> > @Programmatic
> > pubilc OrderItem doCreateItem( .... ) {
> > OrderItem item = ...
> > ...
> > return item;
> > }
> > }
> >
> > I suspect the above pattern/idiom is sufficient in many cases.
> >
> > But if that seems like too much boilerplate, and we really did want to
> have
> > a single method (such that Isis renders the Order even though an
> OrderItem
> > is returned) then I think I'd prefer to simply annotate which of our
> > entities are aggregate roots, ie
> >
> > @AggregateRoot
> > public class Order { ... }
> >
> > Then, the rule would be that if the returned object does not have the
> > AggregateRootFacet, then we instead navigate to the target aggregate
> root.
> >
> > Thoughts?
> > Dan
> >
> >
> >
> >
> > On 3 December 2013 10:01, GESCONSULTOR - Óscar Bou
> > <[email protected]>wrote:
> >
> >>
> >> Really well-looking, Jeroen.
> >>
> >> Regarding navigability through actions, I think that perhaps there are 2
> >> distinct use cases that should be treated differently as such:
> >>
> >> 1. The user creates an Aggregate Root (such as an Order). As such,
> >> normally want to navigate to the newly created one.
> >> 2. The user creates an Entity that is part of an Aggregate (such as an
> >> Order Line / Item). In this case, normally the user wants to stay on the
> >> Order by default. If not, he/she can always navigate by clicking on the
> >> item collections link to the newly created item.
> >>
> >> Implementing that desired default behavior by Isis could be easily done
> >> with an annotation that can be associated with an action, such as
> >> @NotNavigate (sure there are better names :-).
> >>
> >> By default, the Isis framework viewers open the action's returned entity
> >> (such as when invoking Orders.createOrder(...) ), but that behavior
> could
> >> be overridden annotating with @NotNavigate the ( Order.createItem(...) )
> >> action:
> >>
> >> public class Order {
> >>
> >> ...
> >>
> >> @NotNavigate
> >> public OrderItem createItem(...) {
> >> ...
> >> }
> >>
> >> }
> >>
> >>
> >> Currently, we are forced to choose to return void or return an object,
> as
> >> that mandates the Isis viewer behavior. With that annotation, the value
> >> returned does not always imposes the navigation behavior.
> >>
> >> Perhaps there are better solutions or some pitfalls on this proposal.
> >>
> >> HTH,
> >>
> >> Oscar
> >>
> >>
> >>
> >> El 02/12/2013, a las 22:57, Jeroen van der Wal <[email protected]>
> >> escribió:
> >>
> >>> Thanks for reminding Dan, screenshot now as link [1]
> >>>
> >>> [1]
> >>>
> >>
> https://dl.dropboxusercontent.com/u/1930710/Attachments/Screen%20Shot%202013-12-02%20at%2010.03.35%20PM.png
> >>>
> >>>
> >>> On Mon, Dec 2, 2013 at 10:23 PM, Dan Haywood
> >>> <[email protected]>wrote:
> >>>
> >>>> Hi Jeroen,
> >>>> Screenshots get stripped from the mailing list, so you'll need to post
> >> it
> >>>> somewhere online. How about updating the screenshots on Estatio's
> >> README?
> >>>>
> >>>> By the way, I have a further commit... discovered that default values
> >> for
> >>>> parameters are not honoured second time around (ie bring up an action
> >>>> prompt, then cancel, then bring it up again).
> >>>>
> >>>> Cheers
> >>>> Dan
> >>>>
> >>>>
> >>>>
> >>>> On 2 December 2013 21:17, Jeroen van der Wal <[email protected]>
> >> wrote:
> >>>>
> >>>>> The modal dialog really improves the usability, thanks Dan. I've
> >> attached
> >>>>> attached a screenshot which tells more then thousand words.
> >>>>>
> >>>>> I just recently learned that you can use java.lang.Object as the
> return
> >>>>> type of an action and return whatever domain object or collection you
> >>>>> programmatically decide. So your action basically is the controller.
> >>>> Nice!
> >>>>> Sounds familiar to what Oscar is doing.
> >>>>>
> >>>>> Cheers,
> >>>>>
> >>>>> Jeroen
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> On Mon, Dec 2, 2013 at 7:37 PM, GESCONSULTOR - Óscar Bou <
> >>>>> [email protected]> wrote:
> >>>>>
> >>>>>>
> >>>>>>
> >>>>>> Good done.
> >>>>>>
> >>>>>> We also use modal dialogs on our custom viewer to avoid context
> >>>>>> switching. The same dialog redirects to a Domain Object if that's
> the
> >>>>>> result of the action invocation, or currently shows a Collection in
> a
> >>>> grid
> >>>>>> on the same dialog if that's the result of the action. The user can
> >> then
> >>>>>> navigate to any of the objects in the collection.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> El 02/12/2013, a las 17:54, Dan Haywood <
> [email protected]
> >>>
> >>>>>> escribió:
> >>>>>>
> >>>>>>> Hi folks,
> >>>>>>>
> >>>>>>> just an fyi that I've committed and pushed ISIS-486 [1], to render
> >> the
> >>>>>>> Wicket viewer's action prompts in modal dialogs. This should make
> >>>> for
> >>>>>> a
> >>>>>>> better overall user experience.
> >>>>>>>
> >>>>>>> To use, you'll need to build from source, as per [2].
> >>>>>>>
> >>>>>>> In case there are issues, the old behaviour (action prompts on
> their
> >>>> own
> >>>>>>> page) can be enabled by adding the following property:
> >>>>>>>
> >>>>>>> isis.viewer.wicket.disableModalDialogs=true
> >>>>>>>
> >>>>>>> into WEB-INF/viewer_wicket.properties (or isis.properties if you
> >>>>>> prefer).
> >>>>>>> I'll probably remove this original behaviour before pushing out a
> >>>> final
> >>>>>>> release, though.
> >>>>>>>
> >>>>>>> Cheers
> >>>>>>> Dan
> >>>>>>>
> >>>>>>>
> >>>>>>> [1] https://issues.apache.org/jira/browse/ISIS-486
> >>>>>>> [2] http://isis.apache.org/contributors/building-isis.html
> >>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>
> >>
>
>