Last active
December 1, 2016 15:36
-
-
Save martinandersson/e6b7df7903e47acb7370ed6e2c5e46cc to your computer and use it in GitHub Desktop.
Configurator, passed to service by CDI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DefaultFacade implements Facade | |
{ | |
@Inject | |
OrderService service; | |
@Override | |
public void buttonClicked() { | |
Instant dispatch = Instant.now().plus(2, ChronoUnit.HOURS); | |
Order order = service.createOrder(dispatch); | |
// .. | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DefaultService implements OrderService | |
{ | |
@Inject | |
OrderFactory factory; | |
@Inject | |
Instance<OrderConfigurator> cfgInstance; | |
@Override | |
public Order createOrder(Instant dispatchDate) { | |
Order o = factory.createOrder(dispatchDate); | |
OrderConfigurator configurator = getInstanceOrNull(cfgInstance); | |
if (configurator != null) { | |
configurator.configure(order); | |
} | |
return o; | |
} | |
private static <T> T getInstanceOrNull(Instance<? extends T> instance) { | |
try { | |
return instance.get(); | |
} | |
catch (UnsatisfiedResolutionException e) { | |
return null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MyOrderConfigurator implements OrderConfigurator | |
{ | |
@Override | |
public void configure(Order order) { | |
// Do whatever to the order. | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This interface can not be generic. I.e, Configurator<T>. | |
// See https://github.com/MartinanderssonDotcom/java-ee-concepts/blob/master/src/test/java/com/martinandersson/javaee/cdi/resolution/GenericBeanUndeployableTest.java | |
interface OrderConfigurator { | |
void configure(Order order); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is one way to let CDI pass the service an optional order configurator.
We could also let the facade and/or service accept an optional configurator from the client.
Also note that this example is kind of broken. We let the facade determine a default dispatch date (two hours from invocation time) that is sent to the service and then further passed down to the
Order
constructor. Hence, this example claims it is the responsibility of the facade to determine the dispatch date. But, we leave it to another optional entity (OrderConfigurator
) to determine the rest.We have to have a design for what is "reasonable defaults" and who set what. Furthermore, having the configurator outside the
Order
class render theOrder
class inherently mutable. Our configurator might have the responsibility to set "required" fields, but these fields now have the semantics of being "required" only at the time of our database persist.It would be really cool if the service looked up the configurator, but passed this guy to the
Order
constructor. Hence, once the initialization routine (constructor) completes, the order is complete (this does violate a Java language principle that constructors shouldn't be overridable and/or call non-final methods). This would require the base line to have one default order configuration which must be specialized by projects.If it is the case that having a configurator move all logic from the service to the configurator and the service ends up being a single-line method, then the service is the "configurator" and it make no sense to further pollute the type system. Instead, each project should specialize the service itself.