I'm using Guice throughout my code, and I've found a pattern that works rather nicely. Suppose I've got a service interface method for scheduling a delivery:
public interface DeliveryService {
/**
* Schedules {@link order} for delivery and returns a snapshot with
* the details of the scheduled delivery.
*
* @param loggedInUser the customer service rep who is making this request.
* @param selectedCustomer the customer to whom the order will be delivered
* @param order the order to schedule a delivery for
*/
Delivery scheduleDelivery(User loggedInUser,
Customer selectedCustomer, Order order);
}`</pre>The interface does exactly what it needs to do. But since it has so many parameters, calling it is a hassle for the caller. They need to inject the user and customer, only to pass it to the service:
<pre class="prettyprint">public class ScheduleDeliveryAction implements Action {
private final DeliveryService deliveryService;
private final User loggedInUser;
private final Customer selectedCustomer;
private Delivery delivery;
@Inject
public ScheduleDeliveryAction(DeliveryService deliveryService,
User loggedInUser, Customer selectedCustomer) {
this.deliveryService = deliveryService;
this.loggedInUser = loggedInUser;
this.selectedCustomer = selectedCustomer;
}
public String execute() {
/* parse HTTP parameters etc. */
Order order = ...
this.delivery = deliveryService.scheduleDelivery(
loggedInUser, selectedCustomer, order);
return SUCCESS;
}
...
}</pre>
### A better approach
A better approach is have the service know about the logged in user and customer implicitly. I change the real implementation of the service so that it gets the Customer and User injected into it. Now the interface is simpler:
<pre class="prettyprint">`public interface DeliveryService {
/**
* Schedules {@link order} for delivery and returns a snapshot with
* the details of the scheduled delivery.
*
* @param order the order to schedule a delivery for
*/
Delivery scheduleDelivery(Order order);
}
And so is the calling code:
public class ScheduleDeliveryAction implements Action { private final DeliveryService deliveryService; private Delivery delivery; @Inject public ScheduleDeliveryAction(DeliveryService deliveryService) { this.deliveryService = deliveryService; } public String execute() { /* parse HTTP parameters etc. */ Order order = ... this.delivery = deliveryService.scheduleDelivery(order); return SUCCESS; } ... }The other great benefit of this approach is that if we need to add more fields to DeliveryService, we don't need to change the callers. With [Guice](http://code.google.com/p/google-guice/), your code is simpler because you don't need to worry about indirect dependencies.