Iteradores versus 'cursores' em Java

5

Em Java, a maioria das pessoas espera que cada chamada para Iterator.next() retorne um objeto distinto. Isso levou alguns de nós a definir um modelo alternativo que chamamos de 'cursor'. (Observe que outros usam o termo 'cursor' para desenhar uma distinção diferente.) O padrão de um cursor é:

class SomeCursor {
    boolean hasNext();
    void next();
    type1 getItem1();
    type2 getItem2();
 }

Em outras palavras, é perfeitamente claro que o mesmo objeto evolui a cada passo da iteração.

O problema na minha mão agora é também apoiar situações, como serviços da web, em que absolutamente queremos objetos distintos para que possamos enviar uma coleção deles por aí.

Sinto dificuldade em imaginar pares de classes (um cursor e um bean) que precisam ser mantidos em paralelo e estou buscando alternativas.

Aqui está uma ideia, e eu me pergunto se alguém mais viu uma melhor.

  1. Você cria uma interface que consiste nos métodos "get" para um objeto com todos os itens nele.
  2. Você define o cursor como implementando essa interface e também possuiPróximo & a seguir.
  3. Você cria dinamicamente os objetos de bean usando uma das principais bibliotecas dinâmicas de código genérico para criar uma classe com os campos óbvios e obter métodos, além de definir métodos, se necessário, para tornar algo como JAX-B feliz.

edit: para aqueles que não estão seguindo, eu recomendo uma leitura de link . Compare também com o link , que é um exemplo desse 'cursor' abordagem.

Anote no Lucene uma API que itera sobre uma sequência de objetos, permite que o chamador especifique se deseja entregar os novos dados a um novo objeto ou ao mesmo objeto antigo a cada vez.

Sim, é possível definir um Iterator<T> que retorna a mesma coisa sempre, mas temos a preocupação de que as pessoas usem isso como uma arma para disparar os dedos dos pés. Assim, a preferência pelo padrão JDBC-ish.

    
por bmargulies 22.08.2011 / 19:42
fonte

3 respostas

2

Perdoe-me se não estou entendendo o que você quer, mas parece que você está combinando os conceitos de Iterator e Factory / Builder.

Deixe-me fazer algumas considerações aqui.

O padrão Iterator funciona bem para uma coleção homogênea de objetos que você deseja distribuir por meio de uma interface comum. Por exemplo, você tem uma coleção de Strings e quer que elas sejam distribuídas em uma ordem específica para que você use um Comparator (nos bastidores) e seu código consumidor só precise chamar next () algumas vezes para atingir seu objetivo.

O padrão Fábrica cria uma instância de um Objeto de acordo com uma determinada especificação - algumas vezes fornecida como argumentos, algumas vezes inferida. O padrão do Construtor é semelhante, mas geralmente é voltado para a conclusão de uma única etapa no caminho até a conclusão de uma instância de uma coleção composta de Objetos.

Parece a partir do seu exemplo de código que você deseja um mecanismo que permita criar uma instância de um objeto (de tipo variável) em resposta a um determinado número de chamadas. Talvez uma sequência como esta:

next() -> getType1() -> String with "Hello"
next() -> getType2() -> Integer with 4
next() -> getTypeN() -> some function applied -> some type returned

e assim por diante.

Se é isso que você procura, essa abordagem viola o Princípio da menor surpresa. Como desenvolvedor, se um objeto estiver sendo silenciosamente mutado nos bastidores, eu gostaria de saber sobre ele, pois quero conhecer os problemas de encadeamento e desempenho que podem surgir.

Como o problema que parece enfrentar é manter uma coleção de objetos entre chamadas da Web sem estado, é melhor usar uma Lista simples e fornecer o índice para a entrada atual como parte da resposta ao cliente. Quando o cliente solicitar o conteúdo da Lista, simplesmente o entregue ao JAXB para empacotá-lo em XML / JSON (ele usará um Iterator).

Essa abordagem mantém seu código simples e, portanto, impede os desenvolvedores depois de você olhar o código e dizer WTF?

    
por 23.08.2011 / 10:34
fonte
1

Eu realmente não vejo a diferença entre o que você tem aí e o Iterator<T> . O fato de você querer reciclar a instância subjacente em cada iteração ainda é legal, se mal aconselhado.

Pode valer a pena assistir a última apresentação de puzzles de josh bloch. um dos enigmas evolve em torno do iterador EnumMap.entries() reciclando a mesma instância de Map.Entry para cada entrada, certamente quebra o princípio da menor surpresa.

    
por 23.08.2011 / 10:28
fonte
0

Parece-me que você está misturando o conceito de iteradores com o conceito de propriedades do bean Java.

Se você tem uma instância de um bean e deseja iterar através de suas propriedades, existem várias bibliotecas que o ajudarão a fazer isso, como o BeanUtils do Apache commons e o Beanlib:

link

link

    
por 23.08.2011 / 02:13
fonte

Tags