Iterador (padrón de deseño)

En deseño de software, o padrón de deseño **Iterador**, define unha interface que declara os métodos necesarios para acceder secuencialmente a un grupo de obxectos dunha colección. Algúns dos métodos que podemos definir na interface Iterador son:

:primeiro(), seguinte(), haiMais() e elementoActual().

Este padrón de deseño permite percorrer unha estrutura de datos sen que sexa necesario coñecer a estrutura interna da mesma.

## Propósito 
O padrón Iterador é un mecanismo de acceso ós elementos que constitúen unha estrutura de datos para a utilización destes sen expoñer a súa estrutura interna.

## Motivación 
O padrón xorde do desexo de acceder ós elementos dun contedor de obxectos (por exemplo, unha lista) sen expoñer a súa representación interna.
Ademais, é posible que se necesite máis dunha forma de percorrer a estrutura sendo para elo necesario crear modificacións na clase.

A solución que propón o padrón é engadir métodos que permitan percorrer a estrutura sen referenciar explicitamente a súa representación. A responsabilidade do percorrido trasladase a un obxecto iterador.

O problema de introducir este obxecto iterador reside en que os clientes necesitan coñecer a estrutura para crear o iterador apropiado.

Isto solucionase xeneralizando os distintos iteradores nunha abstracción e dotando ás estruturas de datos dun método de fabricación que cree un iterador concreto.

Exemplo do padrón iterador|500px

## Aplicabilidade 
O padrón iterator permite o acceso ó contido dunha estrutura sen expoñer a súa representación interna. Ademais diferentes iteradores poden presentar diferentes tipos de percorrido sobre a estrutura (percorrido de principio a fin, percorrido con saltos...).
Por outro lado os iteradores non teñen por qué limitarse a percorrer a estrutura, senón que poderían incorporar outro tipo de lóxica (por exemplo, filtrado de elementos). É máis, dados diferentes tipos de estruturas, o padrón iterador permite percorrelas todas utilizando unha interface común uniforme.

## Estrutura 
Estrutura do padrón iterador|500px

## Participantes 
As entidades participantes no deseño proposto polo padrón iterador son:

* **Iterador (Iterator):** define a interface para percorrer o agregado de elementos e acceder a eles, de maneira que o cliente non teña que coñecer os detalles e sexa capaz de manexalos de todos modos.
* **Iterador Concreto (ConcreteIterator):** implementa a interface proposta polo Iterador. É o que se encarga de manter a posición actual no percorrido da estrutura.
* **Agregado (Aggregate):** define a interface para o método de fabricación de iteradores.
* **Agregado Concreto (ConcreteAggregate):** implementa a estrutura de datos e o método de fabricación de iteradores que crea un iterador específico para a súa estrutura.

## Colaboracións 
Un iterador concreto é o encargado de gardar a posición actual dentro da estrutura de datos, interactuando con esta para calcular o seguinte elemento do percorrido.

## Consecuencias 
O padrón Iterador permite por tanto diferentes tipos de percorrido dun agregado e varios percorridos simultáneos, simplificando a interface do agregado.

## Implementación 
Para a creación do padrón iterador debe implementarse o control da iteración e definirse o percorrido. O control da iteración pode realizarse de dúas formas:
* **Iterador externo:** ofrece os métodos para que o cliente percorra a estrutura paso a paso (primeiro(), seguinte(), haiMais() e elementoActual()).
* **Iterador interno:** ofrece un método de actuación sobre a estrutura que, de maneira transparente ó cliente, realiza o percorrido de todos os seus elementos aplicando unha determinada operación sobre eles.
A maiores poderíanse implementar operacións adicionais no iterador o definir a estrutura deste dunha maneira máis robusta ante cambios na estrutura.
Hai que ter especial coidado na implementación de iteradores con accesos privilexiados, iteradores para estruturas compostas ou iteradores nulos.

## Exemplo en Java do código dun iterador 
Definición do agregado concreto.

```java
/**
 * Clase que implementa o comportamento dun vector de enteiros.
 */
public class Vector2 
{
    //Array de enteiro onde se almacenaran os datos dos elementos do vector.
    public int[] _datos;

    /**
     * Método constructor da clase Vector2.
     *
     * @param valores Número de elementos que poderán ser almacenados no vector.
     */
    public Vector2(int valores)
    { 
        _datos = new int[valores];
        
        //Inicializamos a cero todos os elementos do vector.
        for (int i = 0; i < _datos.length; i++)
        {
            _datos[i] = 0; 
        }
    }    
    
    /**
     * Método para obter o valor dunha posición do vector.
     *
     * @param pos A posición sobre a que se quere obter o valor.
     * @return O valor que conten o vector na posición indicada como parámetro.
     */
    public int obterValor(int pos)
    { 
        return _datos[pos]; 
    }

    /**
     * Método para asignar un valor a unha posición do vector.
     *
     * @param pos A posición a que se lle quere asignar o valor.
     * @param valor O valor que se quere asignar.
     */
    public void asignarValor(int pos, int valor)
    { 
        _datos[pos] = valor; 
    }

    /**
     * Método para obter o tamaño do vector.
     *
     * @return O tamaño do vector.
     */
    public int dimension()
    { 
        return _datos.length; 
    }
    
    /**
     * Método para obter un interador deste vector.
     *
     * @return Un iterador que permite percorrer o contido deste vector.
     */
    public IteradorVector iterador()
    {
        return new IteradorVector(this); 
    }
}
```

Definición do iterador concreto.

```java
/**
 * Clase que permite percorrer o contido dunha instancia da clase Vector2.
 */
public class IteradorVector
{
    //Array para acceder o contido do vector.
    private int[] _vector;

    //Posición actual na que se atopa o iterador.
    private int _posicion;
 	
    /**
     * Método constructor da clase IteradorVector. 
     * Permite crear un iterador a partir dun Vector2.
     */
    public IteradorVector(Vector2 vector) 
    {
        _vector = vector._datos;

        //O percorrido que realizará o iterador será ascendente polo que inicializamos a posición a 0.
        _posicion = 0; 
    }
 	 	
    /**
     * Método que permite comprobar se hai máis elementos sen percorrer.
     *
     * @return True se hai máis elementos sen percorrer, false en caso contrario.
     */
    public boolean haiMais()
    {
        if (_posicion < _vector.length) 
		 return true;
	 else
		 return false;
    }

    /**
     * Método que devolve o seguinte elemento do vector que percorre este iterador.
     * 
     * @return O valor do seginte elemento do vector.     
     */
    public Object seguinte()
    {
	 int valor = _vector[_posicion];
	 _posicion++;
	 return valor;
    }
}
```

Exemplo de uso:

```java
//Método para probar o uso do noso iterador.
    public static void main(String argv[]) 
    {
        //Creamos un vector de 5 elementos.
    	Vector2 vector = new Vector2(5);
    	
    	//Asignamos valores ós elementos do vector.
    	vector.asignarValor(0, 3);
    	vector.asignarValor(2, 9);    	
    	vector.asignarValor(4, 1);    	
    	
    	//Creación do iterador.
    	IteradorVector iterador = vector.iterador();
    	
    	//Percorrido empregando o iterador.
    	while(iterador.hasNext())
            System.out.println(iterador.next());    	    	
    }
```

En java xa existe unha interface Iterator que fai ás veces de abstracción. Tódolos iteradores utilizados nas súas librerías cumpren esta interface, o que permite tratalos a todos eles de maneira uniforme.

Facer que o noso IteradorVector implementase Iterator permitiría que fose utilizado por outras librerías e programas de maneira transparente.

```java
import java.util.Iterator;

/**
 * Clase que permite percorrer o contido dunha instancia da clase Vector2.
 * Esta clase implementa a interface Iterator de Java.
 */
public class IteradorVector implements Iterator
{
    //Array para acceder o contido do vector.
    private int[] _vector;

    //Posición actual na que se atopa o iterador.
    private int _posicion;

    /**
     * Método constructor da clase IteradorVector. 
     * Permite crear un iterador a partir dun Vector2.
     */
    public IteradorVector(Vector2 vector) 
    {
        _vector = vector._datos;

        //O percorrido que realizará o iterador será ascendente polo que inicializamos a posición a 0.
        _posicion = 0; 
    }

    /**
     * Método que permite comprobar se hai máis elementos sen percorrer.
     *
     * @return True se hai máis elementos sen percorrer, false en caso contrario.
     */
    public boolean hasNext()
    {
        if (_posicion < _vector.length)
            return true;
        else
            return false;
    }

    /**
     * Método que devolve o seguinte elemento do vector que percorre este iterador.
     * 
     * @return O valor do seguinte elemento do vector.
     */
    public Object next()
    {
        int valor = _vector[_posicion];
        _posicion++;
        return valor;
    }

    /**
     * Método para elimina do vector o último elemento devolto por este iterador.
     * A implementación deste método é opcional. Neste caso decidiuse lanzar unha excepción de operación non soportada.
     */
    public void remove()
    {
        throw new UnsupportedOperationException("Operación non soportada.");
    }
}
```