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
MyComponent
extendSlowLoading
. 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
MyComponentImpl
directly 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
SlowLoading
thing. This seems the most appropriate, but I've not been able to get this working so far.