stringtranslate.com

Patrón iterador

En la programación orientada a objetos , el patrón iterador es un patrón de diseño en el que se utiliza un iterador para recorrer un contenedor y acceder a los elementos del contenedor. El patrón iterador desacopla los algoritmos de los contenedores; en algunos casos, los algoritmos son necesariamente específicos del contenedor y, por lo tanto, no se pueden desacoplar.

Por ejemplo, el algoritmo hipotético SearchForElement se puede implementar de forma general utilizando un tipo específico de iterador en lugar de implementarlo como un algoritmo específico del contenedor. Esto permite que SearchForElement se utilice en cualquier contenedor que admita el tipo de iterador requerido.

Descripción general

El patrón de diseño Iterador [1] es uno de los 23 patrones de diseño conocidos del "Banda de los Cuatro" que describen cómo resolver problemas de diseño recurrentes para diseñar software orientado a objetos flexible y reutilizable, es decir, objetos que son más fáciles de implementar, cambiar, probar y reutilizar.

¿Qué problemas puede resolver el patrón de diseño Iterador?

[2]

La definición de operaciones de acceso y recorrido en la interfaz agregada es inflexible porque compromete el agregado con operaciones de acceso y recorrido particulares y hace imposible agregar nuevas operaciones más tarde sin tener que cambiar la interfaz agregada.

¿Qué solución describe el patrón de diseño Iterador?

Se pueden utilizar distintos iteradores para acceder y recorrer un agregado de distintas maneras.
Se pueden definir nuevas operaciones de acceso y recorrido de forma independiente mediante la definición de nuevos iteradores.

Vea también el diagrama de clases y secuencias UML a continuación.

Definición

La esencia del patrón Iterador es "Proporcionar una forma de acceder a los elementos de un objeto agregado secuencialmente sin exponer su representación subyacente". [3]

Estructura

Diagrama de clases y secuencias UML

Un ejemplo de diagrama de clase y secuencia UML para el patrón de diseño Iterador. [4]

En el diagrama de clases UML anterior , la clase hace referencia (1) a la interfaz para crear un objeto ( ) y (2) a la interfaz para recorrer un objeto ( ). La clase implementa la interfaz accediendo a la clase.ClientAggregateIteratorcreateIterator()IteratorAggregatenext(),hasNext()Iterator1IteratorAggregate1

El diagrama de secuencia UML muestra las interacciones en tiempo de ejecución: el objeto llama a un objeto, que crea un objeto y lo devuelve al . Luego, utiliza para recorrer los elementos del objeto.ClientcreateIterator()Aggregate1Iterator1ClientClientIterator1Aggregate1

Diagrama de clases UML

El patrón iterador

Ejemplo

Algunos lenguajes estandarizan la sintaxis. C++ y Python son ejemplos notables.

C++

C++ implementa iteradores con la semántica de los punteros de ese lenguaje. En C++, una clase puede sobrecargar todas las operaciones de puntero, por lo que se puede implementar un iterador que actúe más o menos como un puntero, con desreferencia, incremento y decremento incluidos. Esto tiene la ventaja de que los algoritmos de C++ como std::sortpueden aplicarse inmediatamente a los buffers de memoria tradicionales y que no hay una nueva sintaxis que aprender. Sin embargo, requiere un iterador "final" para comprobar la igualdad, en lugar de permitir que un iterador sepa que ha llegado al final. En el lenguaje C++, decimos que un iterador modela el concepto de iterador .

Esta implementación de C++11 se basa en el capítulo "Generalizando el vector una vez más". [5]

#include <iostream> #include <stdexcept> #include <lista_inicializador> clase Vector { público : using iterador = double * ; iterador begin () { devolver elem ; } iterador end () { devolver elem + sz ; } Vector ( std :: lista_inicializador < double > lst ) : elem ( nullptr ), sz ( 0 ) { sz = lst.size ( ); elem = new double [ sz ]; double * p = elem ; for ( auto i = lst.begin (); i ! = lst.end ( ) ; ++ i , ++ p ) { * p = * i ; } } ~ Vector ( ) { eliminar [ ] elem ; } int tamaño () const { devolver sz ; } operador doble & []( int n ) { si ( n < 0 || n >= sz ) arrojar std :: fuera_de_rango ( "Vector::operador[]" ); devolver elem [ n ]; } Vector ( const Vector & ) = eliminar ; // regla de tres Operador Vector & = ( const Vector & ) = eliminar ; privado : doble * elem ; int sz ; };                                                                                                    int main () { Vector v = { 1.1 * 1.1 , 2.2 * 2.2 }; para ( const auto & x : v ) { std :: cout << x << '\n' ; } para ( auto i = v . begin (); i != v . end (); ++ i ) { std :: cout << * i << '\n' ; } para ( auto i = 0 ; i <= v . size (); ++ i ) { std :: cout << v [ i ] << '\n' ; } }                                                      

La salida del programa es

1.21 4.84 1.21 4.84 1.21 4.84 terminar llamado después de lanzar una instancia de ' std :: out_of_range ' what () : Vector :: operator []         

Véase también

Referencias

  1. ^ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Patrones de diseño: elementos de software orientado a objetos reutilizable . Addison Wesley. pp. 257ff. ISBN 0-201-63361-2.
  2. ^ "El patrón de diseño Iterator: problema, solución y aplicabilidad". w3sDesign.com . Consultado el 12 de agosto de 2017 .
  3. ^ Banda de los cuatro
  4. ^ "El patrón de diseño Iterator - Estructura y colaboración". w3sDesign.com . Consultado el 12 de agosto de 2017 .
  5. ^ Bjarne Stroustrup (2014). Programación: principios y práctica con C++ (2.ª ed.). Addison Wesley. pp. 729 y siguientes. ISBN 978-0-321-99278-9.

Enlaces externos