Ho il concetto di una cosa SlowLoading
:
public interface SlowLoading {
boolean hasLoaded();
}
Ho anche un componente MyComponent
:
public interface myComponent{
void doSomething();
}
La mia implementazione copre entrambi:
public class MyComponentImpl implements SlowLoading, MyComponent {
// omitted for brevity
}
Ho un contenitore (interfaccia omessa per brevità) che restituisce MyComponent
:
public class MyContainerImpl implements MyContainer{
@Inject private MyComponent component;
@Override
public MyComponent doSomething(){
// magic happens
return myComponent;
}
}
Ho anche un componente AOP che intercetta il ritorno del caricamento lento delle cose e attende implicitamente che vengano caricate prima di tornare:
@Pointcut("execution(SlowLoading+ *(..) )")
public void returnsSlowLoadingThing() {
}
Tuttavia, al momento il metodo MyContainer
non è proxy, poiché il valore restituito non implementa SlowLoading
.
Qual è il modo migliore per incapsulare questo comportamento?
Opzioni che ho considerato:
- Crea
MyComponent
estendiSlowLoading
. Questo sembra un odore di codice e la rottura di incapsulamento - implementazione sanguinante nell'interfaccia. A un cliente non interessa se è lento o meno. - Inietta
MyComponentImpl
direttamente nel mio contenitore e restituiscilo esplicitamente (restituzioni in co-variante). Ancora una volta, sembra che stia rompendo l'incapsulamento e il punto di programmazione delle interfacce, ma si sente meglio di quanto sopra, dal momento che è fatto a un livello inferiore e nascosto dietro l'interfaccia (dettagli di implementazione). Tuttavia sta rompendo l'incapsulamento della funzionalità AOP che dovrebbe essere ortogonale e trasparente. - Esegui l'attesa AOP prima di richiamare un metodo su una cosa
SlowLoading
. Questo sembra il più appropriato, ma non sono stato in grado di farlo funzionare così lontano.