Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Actions have three responsibilities.  four parts to them (responsibliities, I suppose):

  • execution +
  • supporting methods for perform the validation etc
  • to specify the target object that they act upon
  • event publishing

Our programming model could provide several syntaxes to put these responsibilities in different places.  It already supports two (standard actions, and mixins).

...

Code Block
public class Customer {                                                                                            // target
    ...
    public static class PlaceOderEvent extends ActionDomainEvent<Customer> {}                                      

    @Action(domainEvent = PlaceOrderEvent.class)                                                                   // event publishing 
    public Customer placeOrder(Product p, int quantity) { ... }                                                    // execution

    public boolean hidePlaceOrder() { return this.isBlackListed(); }                                               // supporting methods
    public String disablePlaceOrder() { return clockService.outsideShoppingHours(); }
    public String disable1PlaceOrder(Product p) { return p.isOutOfStock() ? "Out of stock": null; }                // could also hide parameters similarly
    public Collection<Product> choices0PlaceOrder() { ... }                                                        // or autoComplete0PlaceOrder(String search) { ... }
    public Product default0PlaceOrder() { return orderService.findLastProductPurchasedBy(this); }
    public int default1PlaceOrder() { return 1; }
    public String validate1PlaceOrder(int quantity) { return quantity <= 0 ? "Can only order +ve amounts": null; }
    public String validatePlaceOrder(Product p, int quantity) { return catalogService.runningLowOn(p) && quantity > 4 ? "We're running low on that product, no more than 4" : null; }

    ...
    @Inject CatalogService catalogService;
    @Inject ClockService clockService;
    @Inject OrderService orderService;
}

Notes:

  • For disable1PlaceOrder(), we could also hide individual parameters similarly
  • Instead of choices0PlaceOrder(), we could have used autoComplete0PlaceOrder(String)

Standard syntax

The standard syntax uses regular methods on the target object.  Naming conventions are used to associate the action with supporting methods (default, choices, hide, disable and validate).

...

Code Block
public class Customer {

    
    public Customer placeOrder(Product p, int quantity) { ... }
    public boolean hidePlaceOrder() { ... }
    public String disablePlaceOrder() { ... }
    public String disable1PlaceOrder(Product p) { ... }
    public Collection<Product> choices0PlaceOrder() { ... }
    public Product default0PlaceOrder() { ... }
    public int default1PlaceOrder() { ... }
    public String validate1PlaceOrder(int quantity) { ... }
    public String validatePlaceOrder(Product p, int quantity) { ... }
}

...

Per this thread on slack, we could introduce a Parameters object (in Java 14+, this might be a record) to bring together all of the parameters into a single object.  This would make it easier to avoid issues with numbering etc.

This syntax 

Code Block
languagejava
public class Customer {

    @Value @Accessors(fluent = true)    
    public class PlaceOrderParameters {
        Product product;
        int quantity;
    }

    public Customer placeOrder(Product p, int quantity) { ... }

    public boolean hidePlaceOrder() { ... }
    public String disablePlaceOrder() { ... }
    public String disable1PlaceOrder(PlaceOrderParameters params) { ... }
    public Collection<Product> choices0PlaceOrder() { ... }              
    public Product default0PlaceOrder() { ... }
    public int default1PlaceOrder() { ... }
    public String validate1PlaceOrder(PlaceOrderParameters params) { ... }
    public String validatePlaceOrder(PlaceOrderParameters params) { ... }
}

...

The above would also be supported with mixins:

Code Block
@Action
public class Customer_placeOrder {

 

...

 

...

 

...

 

...

@Value 

...

@Accessors(

...

fluent = true) 

...

   

...


 

...

 

...

 

...

 

...

public static class 

...

PlaceOrderParameters {

...


        Product product;
        int quantity;
    }

    public Customer act(Product p, int quantity) { ... }

...



    public boolean hideAct() { ... }

...


    public String disableAct() { ... }

...


    public String disable1Act(

...

PlaceOrderParameters 

...

params) { ... }

...


    public Collection<Product> choices0Act() { ... }

...

              
    public Product default0Act() { ... }

...


    public int default1Act() { ... }

...


    public String validate1Act(

...

PlaceOrderParameters 

...

params) { ... }

...


    public String validateAct(

...

PlaceOrderParameters params) { ... }

...


}


Parameters on Act syntax (proposed)

This is a variant of the previous, but uses the parameters class in the action as well:This would also be supported within mixins, for no extra work