Sì, questo può facilmente essere fatto in Java 7 e ancora più pulito utilizzando Java 8.
Il parametro per il metodo di method
dovrebbe essere un java.util.function.Supplier<T>
e il parametro per il metodo di until
dovrebbe essere un java.util.function.Predicate<T>
.
È quindi possibile utilizzare i riferimenti metodo o espressioni lambda per creare voi Poller in questo modo:
myMethodPoller.poll(pollDurationInteger, intervalInMillisecond)
.method(payment::getStatus)
.until (paymentStatus -> paymentStatus.getValue().equals("COMPLETED"))
.execute();
Come nota a margine, se avete intenzione di usare Java 8, mi consiglia di utilizzare invece di java.time.Duration
un numero intero per rappresentare la durata del sondaggio e l'intervallo.
Suggerirei anche di esaminare https://github.com/rholder/guava-retrying che è una libreria che è possibile utilizzare. In caso contrario, potrebbe essere una buona fonte di ispirazione per la tua API poiché presenta una buona API fluente.
MODIFICA: Dopo l'aggiornamento alla domanda, ecco una semplice implementazione. Ho lasciato alcune parti da completare come TODO.
import java.time.Duration;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class MethodPoller<T> {
Duration pollDurationSec;
int pollIntervalMillis;
private Supplier<T> pollMethod = null;
private Predicate<T> pollResultPredicate = null;
public MethodPoller() {
}
public MethodPoller<T> poll(Duration pollDurationSec, int pollIntervalMillis) {
this.pollDurationSec = pollDurationSec;
this.pollIntervalMillis = pollIntervalMillis;
return this;
}
public MethodPoller<T> method(Supplier<T> supplier) {
pollMethod = supplier;
return this;
}
public MethodPoller<T> until(Predicate<T> predicate) {
pollResultPredicate = predicate;
return this;
}
public T execute()
{
// TODO: Validate that poll, method and until have been called.
T result = null;
boolean pollSucceeded = false;
// TODO: Add check on poll duration
// TODO: Use poll interval
while (!pollSucceeded) {
result = pollMethod.get();
pollSucceeded = pollResultPredicate.test(result);
}
return result;
}
}
uso Esempio:
import static org.junit.Assert.assertTrue;
import java.util.UUID;
import org.junit.Test;
public class MethodPollerTest
{
@Test
public void test()
{
MethodPoller<String> poller = new MethodPoller<>();
String uuidThatStartsWithOneTwoThree = poller.method(() -> UUID.randomUUID().toString())
.until(s -> s.startsWith("123"))
.execute();
assertTrue(uuidThatStartsWithOneTwoThree.startsWith("123"));
System.out.println(uuidThatStartsWithOneTwoThree);
}
}
Bene, per quanto riguarda il metodo stesso, è possibile avere un riferimento all'oggetto di destinazione, al relativo Metodo riflesso e agli argomenti richiesti. Puoi anche incapsularlo in un lambda, ma sicuramente dipende da come viene passato quel metodo - esplicitamente o scoperto? per quanto riguarda i parametri? –
@rails Se la risposta che ho fornito la soddisfa, per favore accettala. Non esitare se hai ulteriori domande. – GuiSim