I have the concept of a SlowLoading thing:
public interface SlowLoading {
boolean hasLoaded();
}
I also have a component MyComponent:
public interface myComponent{
void doSomething();
}
My implementation covers both:
public class MyComponentImpl implements SlowLoading, MyComponent {
// omitted for brevity
}
I have a container (interface omitted for brevity) which returns MyComponent:
public class MyContainerImpl implements MyContainer{
@Inject private MyComponent component;
@Override
public MyComponent doSomething(){
// magic happens
return myComponent;
}
}
I also have an AOP component that intercepts the return of slow loading things and implicitly waits for them to load before returning:
@Pointcut("execution(SlowLoading+ *(..) )")
public void returnsSlowLoadingThing() {
}
However, at present the MyContainer method is not proxied, since the return value does not implement SlowLoading.
What is the best way to encapsulate this behaviour?
Options I've considered:
- Make
MyComponentextendSlowLoading. This feels like a code smell and breaking of encapsulation - bleeding implementation into the interface. A client does not care if it is slow loading or not. - Inject
MyComponentImpldirectly into my container and return it explicitly (co-variant returns). Again, this feels like it is breaking encapsulation and the point of programming to interfaces, but feels better than the above, since it is done at a lower level and hidden behind the interface (implementation detail). However it is breaking the encapsulation of the AOP functionality which should be orthogonal and transparent. - Perform the AOP wait before invoking a method on a
SlowLoadingthing. This seems the most appropriate, but I've not been able to get this working so far.