É boa idéia usar Optional.orElseGet fazer alguma lógica logging

lapkritinis:

Eu quero usar opcional para lidar com valores nulos, a parte "complicado", que eu não consigo pensar em qual é a melhor maneira de fazer - é que eu quero fazer o registo se o valor é nulo. Eu posso conseguir isso com seguinte código - mas se sente estranho.

(Update: Eu afixei minha própria resposta, com opcional de Java 9)

Vamos dizer que aparência código como este:

// logLine.getSomeProperty returns Optional<String>

List<LogDetails> logDetails = logLine.getSomeProperty()
    .map(this::extractLogDetails)
    .orElseGet(() -> logError(logLine));
List<LogDetails> extractLogDetails(String s) {
    List<LogDetails> logDetails = new ArrayList<>();
    String sp = "(?:([A-Z0-9]{5,7})-([A-Z0-9]{9})-(.{4}))"; 
    Pattern p = Pattern.compile(sp, Pattern.CASE_INSENSITIVE);
    Matcher m = p.matcher(s);
    while (m.find()) {
        logDetails.add(new LogDetails(m.group(1), m.group(2), m.group(3)));
    }
    return logDetails;
}
List<LogDetails> logError(LogLine logLine) {
    log.error("Error while ... {} ", logLine));
    persistence.setErrorStatus(logLine, FAILED_PARSING);
    return new ArrayList<>();
}

Ele faria o que eu quero, mas eu tenho vários "problemas" com ele.

  • Achei estranho, que o método chamado orElseGeté usado para erros de registro.
  • Eu poderia substituir orElseGet com orElseThrow e logError lá e não jogar nada - o que eu não gosto de qualquer um.
  • método logError retorna lista que eu não uso e parece estranho para retornar algo do método que deve ser anulada.
  • Simplesmente deve haver maneira melhor
  • Casos em que someProperty não é nulo, mas não há partidas - Eu gostaria de registrar bem, mas por que eu precisaria de uma outra linha de código para verificar se logDetails.size() == 0
JBX:

A orElseGetnão é realmente concebido como um mecanismo de tratamento de erros, mas como uma maneira de gerar um valor padrão diferente no caso da Optionalinstância não está realizando qualquer.

Se você quiser verificar se o Optionalestá vazia explicitamente, basta usar o Optional.isPresent()cheque, e fazer o logError()nesse caso.

O que você precisa pensar primeiro é, se o Optionalestiver vazia, o que você quer fazer? Além de log de erro, você quer continuar com uma lista vazia?

Se sim, então você poderia ter algo como isto:

List<LogDetails> logDetails = logLine.getSomeProperty()
    .map(this::extractLogDetails)
    .orElseGet(Collections::emptyList);

Depois que você pode fazer:

if (logDetails.isEmpty()) {
  logError(logline);
}

Alternativamente, se você não quer ter uma lista vazia em tudo, você pode manter as coisas a nível opcional. Desta forma, ambos os casos em que a getSomeProperty()é vazio ou quando a lista gerada é vazio são tratados da mesma maneira.

Optional<List<LogDetails>> logDetailsOpt = logLine.getSomeProperty() 
                       .map(this::extractLogDetails)
                       .filter(list -> !list.isEmpty());

if (!logDetailsOpt.isPresent()) {
  logError(logLine);
}

Em ambos os casos, logError()não é esperado para retornar nada. Ele está fazendo o que pretende fazer em seu nome, registrando o erro.

Ao invés de tentar abusar da funcionalidade de Optional, tentar fazer com que suas intenções em seu código claro. Há mais valor em legibilidade.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=236002&siteId=1
Recomendado
Clasificación