Java Iterator поддерживается сетевым подключением - PullRequest
4 голосов
/ 25 января 2012

С некоторой частотой я пишу API, которые предлагают Iterator<Foo>, который поддерживается сетевым подключением.Реализация открывает сетевое соединение, считывает информацию из потока и десериализует эту информацию в Foo s для передачи вызывающей стороне.К сожалению, всегда есть возможность IOException, а также необходимость корректно закрыть сетевое соединение (это можно сделать автоматически, когда вызывающий абонент читает последний Foo, но что, если этого не произойдет?).

Уже есть пара вопросов ( здесь и здесь ) о том, как обращаться с проверенными исключениями, которые будут выброшены при реализации Iterator, и о принятыхсовет "заверните их в непроверенные RuntimeException с".Между тем, чтобы разрешить закрытие сетевого соединения, мы можем реализовать Closeable.Таким образом, мы получаем что-то вроде этого для хорошо вызывающего вызывающего вызывающего абонента:

Iterator<Foo> iter = null;
try {
    iter = getFooIterator();
    while(iter.hasNext()) {
        Foo foo = iter.next();
        // do something with foo
    }
}
catch(RuntimeException e) {
    if(e.getCause() instanceof IOException) {
       // do something with the IOException
    }
    else throw e;
}
finally {
    if(iter instanceof Closeable) try { ((Closeable)iter).close(); } catch(IOException e) {}
}

И кажется, что такая хорошая идея реализовать Iterator.Есть ли лучший способ?

1 Ответ

1 голос
/ 25 января 2012

IMO первым шагом было бы заключить его в исключение для конкретной реализации или приложения, исключив необходимость перехвата общих RuntimeException s или проверки основной причины.

Я бы рассмотрел конкретную реализацию, чтобы избежать закрываемой проверки и обернуть IOException.

NetworkIterator<Foo> iter = null;
try {
    iter = getFooIterator();
    while (iter.hasNext()) {
        Foo foo = iter.next();
        // do something with foo
    }
} catch (NetworkIteratorExceptiom e) {
    // do something with the IOException
} finally {
    iter.close();
}

Я, вероятно, не смог бы дать ему способ убрать шаблон, но я бы соблазнился; примерно:

NetworkIterator<Foo> iter = new IteratorThang<Foo>() {
    @Override public void each(Foo foo) {
        // Do something with foo
    }
};
...