Patrón de iterador (tipo de comportamiento)

El patrón de iterador es un patrón de diseño muy común en entornos de programación Java y .Net. Este modo se utiliza para acceder secuencialmente a los elementos de un objeto de colección sin conocer la representación subyacente del objeto de colección.

El patrón iterador es un patrón de comportamiento.

Introduccion

Intención: proporcionar un método para acceder secuencialmente a los elementos de un objeto agregado sin exponer la representación interna del objeto.

La solución principal: diferentes formas de atravesar todo el objeto integrado.

Cuándo usar: iterar sobre un objeto agregado.

Cómo resolverlo: asigne al iterador la responsabilidad de caminar entre elementos, no el objeto agregado.

Código clave: defina la interfaz: hasNext, next.

Ejemplo de aplicación: iterador en JAVA.

Ventajas:  1. Soporta atravesar un objeto agregado de diferentes maneras. 2. El iterador simplifica la clase de agregación. 3. Puede haber múltiples recorridos en la misma agregación. 4. En el modo iterador, es muy conveniente agregar nuevas clases de agregación e iterador sin modificar el código original.

Desventajas: debido a que el modo iterador separa la responsabilidad de almacenar datos y atravesarlos, agregar una nueva clase de agregación requiere agregar correspondientemente una nueva clase de iterador. El número de clases aumenta en pares, lo que aumenta la complejidad del sistema en cierta medida.

Escenarios de uso:  1. Acceda al contenido de un objeto agregado sin exponer su representación interna. 2. Es necesario proporcionar múltiples métodos de recorrido para objetos agregados. 3. Proporcione una interfaz unificada para atravesar diferentes estructuras de agregación.

Nota: El patrón iterador es separar el comportamiento transversal del objeto de colección y abstraer una clase de iterador responsable. Esto no solo puede exponer la estructura interna de la colección, sino que también permite que el código externo acceda de manera transparente a los datos dentro de la colección.


manifestación

Defina una clase de elemento de menú con precio de menú, nombre y atributos de descripción,

Hay dos restaurantes, DinerMenu y pancakeHourseMenu. Pueden agregar elementos de menú para obtener la colección de menús.

Waitress Waitress, responsable de imprimir su colección de menús de acuerdo con los diferentes restaurantes.

Definir una interfaz de menú.

package menu;

import item.MenuItem;

public interface Menu
{
     /**
      * 添加菜单项
      * @param name
      * @param description
      * @param price
      */
     void addItem(String name, String description, double price);

     /**
      * 获取菜单项集合
      */
     Object getMenuItems();
}

Definir una clase de elemento de menú.

package item;

/**
 * 菜单项
 */
public class MenuItem
{
	private String name;              //菜单项名称
	private String description;       //描述
	private double price;             //价格
 
	public MenuItem(String name,
                    String description,
                    double price)
	{
		this.name = name;
		this.description = description;
		this.price = price;
	}

	public String toString()
	{
		return (name + ": "+description+", $" + price);
	}
}

Definir dos clases de restaurantes, implementan la interfaz del menú.

package menu;

import item.MenuItem;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * 煎饼屋餐厅
 */
public class PancakeHouseMenu implements Menu
{
	private ArrayList<MenuItem> menuItems;
 
	public PancakeHouseMenu()
	{
		menuItems = new ArrayList();
    
		addItem("薄煎饼早餐",
			"薄煎饼、鸡蛋和土司",
			2.99);
 
		addItem("蓝莓薄煎饼",
			"新鲜蓝莓和蓝莓果酱做成的薄煎饼",
			2.99);
 
		addItem("松饼",
			"松饼,可以选择蓝莓或者草莓口味",
			3.59);
	}

	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description, price);
		menuItems.add(menuItem);
	}


	public ArrayList<MenuItem> getMenuItems()
	{
		return menuItems;
	}

}
package menu;

import item.MenuItem;
import iterator.DinerMenuIterator;
import java.util.Iterator;

/**
 * 对象村餐厅
 */
public class DinerMenu implements Menu
{
    private static final int MAX_ITEMS = 4;
    private int numberOfItems = 0;
    private MenuItem[] menuItems;
  
	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];
 
		addItem("素食 BLT", "(煎)培根, 生菜和西红柿",  2.99);
		addItem("清汤", "一碗清汤, 配土豆沙拉", 3.29);
		addItem("热狗", "一个热狗, 酸菜, 芝士, 洋葱",  3.05);
		addItem("清蒸时蔬加糙米", "清蒸的蔬菜配糙米", 3.99);
	}
  
	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description,  price);
		if (numberOfItems >= MAX_ITEMS)
		{
			System.err.println("抱歉, 菜单已满! 不能添加菜单项");
		}
		else
		{
			menuItems[numberOfItems] = menuItem;
			numberOfItems = numberOfItems + 1;
		}
	}

	public MenuItem[] getMenuItems()
	{
		return menuItems;
	}

}

Defina un camarero, puede estar en el menú de acuerdo con el nombre del restaurante

import item.MenuItem;
import menu.DinerMenu;
import menu.PancakeHouseMenu;

import java.util.ArrayList;

/**
 * 服务员类,根据餐厅打印菜单
 */
public class Waitress
{
	private PancakeHouseMenu pancakeHouseMenu;
	private DinerMenu dinerMenu;

	public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
		this.pancakeHouseMenu = pancakeHouseMenu;
		this.dinerMenu = dinerMenu;
	}

	/**
	 * 打印煎饼屋菜单
	 */
	public void printPancakeHouseMenu() {
		ArrayList<MenuItem> pancakeHouseItems = pancakeHouseMenu.getMenuItems();

		for (int i = 0; i < pancakeHouseItems.size(); i++)
		{
			MenuItem menuItem = pancakeHouseItems.get(i);
			System.out.println(menuItem);
		}
		System.out.println("\n");
	}

	/**
	 * 打印餐厅村菜单
	 */
	public void printdinerMenu() {
		MenuItem[] menuItems = dinerMenu.getMenuItems();

		for (int i = 0; i < menuItems.length; i++)
		{
			MenuItem menuItem = menuItems[i];
			System.out.println(menuItem);
		}
		System.out.println("\n");
	}
}

Clase de prueba

import menu.DinerMenu;
import menu.PancakeHouseMenu;

public class Test
{
    public static void main(String[] args)
    {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();

        Waitress waitress=new Waitress(pancakeHouseMenu,dinerMenu);

        System.out.println("煎饼屋餐厅菜单------------------------");
        waitress.printPancakeHouseMenu();

        System.out.println("对象村餐厅菜单-------------------------");
        waitress.printdinerMenu();
    }
}

Se puede ver en el ejemplo anterior que el método de imprimir menús en el camarero es recorrer el menú de cada restaurante, lo cual es muy problemático. Primero, los atributos del camarero deben ser dos tipos de restaurantes específicos. Si el tipo de colección es diferente, la operación durante el recorrido también es diferente.Si agrega otro restaurante y su tipo de menú, necesita un tercer método de bucle

Pensamiento: si podemos encontrar una manera de hacer que los elementos del menú de cada restaurante implementen la misma interfaz sin cambiar el tipo de colección de los elementos del menú, esto puede minimizar la referencia específica en el código de recepcionista y también puede eliminar Itere a través de los múltiples bucles necesarios para estos dos menús, desacople a la recepcionista del restaurante y entregue la operación de configuración al iterador

Primero en el diagrama de clase

Paso: primero creamos un iterador

package iterator;

import item.MenuItem;

/**
 * 自定义一个迭代器接口
 */
public interface Iterator<E>
{
    boolean hasNext();
    MenuItem next();
}

Ahora necesitamos agregar su propio iterador para cada restaurante

package iterator;

import item.MenuItem;

public class DinerMenuIterator implements Iterator
{
    private MenuItem[] menuItems;
    private int position = 0;

    public DinerMenuIterator(MenuItem[] menuItems)
    {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext()
    {
        if (position >= menuItems.length || menuItems[position] == null)
            return false;
        else
            return true;
    }

    @Override
    public MenuItem next()
    {
        MenuItem menuItem = menuItems[position++];
        return menuItem;
    }
}
package iterator;

import item.MenuItem;

import java.util.ArrayList;

public class PancakeHouseMenuIterator implements Iterator
{
	ArrayList<MenuItem> items;
	int position = 0;
 
	public PancakeHouseMenuIterator(ArrayList<MenuItem> items)
	{
		this.items = items;
	}
 
	public MenuItem next()
	{
		MenuItem item = items.get(position);
		position = position + 1;
		return item;
	}
 
	public boolean hasNext()
	{
		if (position >= items.size())
			return false;
		 else
			return true;
	}
}

Luego agregue un método createIterator () en cada restaurante

package menu;

import item.MenuItem;
import iterator.PancakeHouseMenuIterator;

import java.util.ArrayList;
import iterator.Iterator;

/**
 * 煎饼屋餐厅
 */
public class PancakeHouseMenu implements Menu
{
	private ArrayList<MenuItem> menuItems;
 
	public PancakeHouseMenu()
	{
		menuItems = new ArrayList();
    
		addItem("薄煎饼早餐",
			"薄煎饼、鸡蛋和土司",
			2.99);
 
		addItem("蓝莓薄煎饼",
			"新鲜蓝莓和蓝莓果酱做成的薄煎饼",
			2.99);
 
		addItem("松饼",
			"松饼,可以选择蓝莓或者草莓口味",
			3.59);
	}

	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description, price);
		menuItems.add(menuItem);
	}


	public ArrayList<MenuItem> getMenuItems()
	{
		return menuItems;
	}

	public Iterator<MenuItem> createIterator() {
		return  new PancakeHouseMenuIterator(menuItems);
	}
}
package menu;

import item.MenuItem;
import iterator.DinerMenuIterator;
import iterator.Iterator;

/**
 * 对象村餐厅
 */
public class DinerMenu implements Menu
{
    private static final int MAX_ITEMS = 4;
    private int numberOfItems = 0;
    private MenuItem[] menuItems;
  
	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];
 
		addItem("素食 BLT", "(煎)培根, 生菜和西红柿",  2.99);
		addItem("清汤", "一碗清汤, 配土豆沙拉", 3.29);
		addItem("热狗", "一个热狗, 酸菜, 芝士, 洋葱",  3.05);
		addItem("清蒸时蔬加糙米", "清蒸的蔬菜配糙米", 3.99);
	}
  
	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description,  price);
		if (numberOfItems >= MAX_ITEMS)
		{
			System.err.println("抱歉, 菜单已满! 不能添加菜单项");
		}
		else
		{
			menuItems[numberOfItems] = menuItem;
			numberOfItems = numberOfItems + 1;
		}
	}

	public MenuItem[] getMenuItems()
	{
		return menuItems;
	}

	@Override
	public Iterator<MenuItem> createIterator() {
		return new DinerMenuIterator(menuItems);
	}


}

Modificar la clase de camarero en este momento

import item.MenuItem;
import menu.DinerMenu;
import menu.PancakeHouseMenu;

import java.util.ArrayList;
import iterator.Iterator;

/**
 * 服务员类,根据餐厅打印菜单
 */
public class Waitress
{
	private PancakeHouseMenu pancakeHouseMenu;
	private DinerMenu dinerMenu;

	public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
		this.pancakeHouseMenu = pancakeHouseMenu;
		this.dinerMenu = dinerMenu;
	}

	/**
	 * 打印煎饼屋菜单
	 */
	public void printPancakeHouseMenu() {
		ArrayList<MenuItem> pancakeHouseItems = pancakeHouseMenu.getMenuItems();

		for (int i = 0; i < pancakeHouseItems.size(); i++)
		{
			MenuItem menuItem = pancakeHouseItems.get(i);
			System.out.println(menuItem);
		}
		System.out.println("\n");
	}

	/**
	 * 打印餐厅村菜单
	 */
	public void printdinerMenu() {
		MenuItem[] menuItems = dinerMenu.getMenuItems();

		for (int i = 0; i < menuItems.length; i++)
		{
			MenuItem menuItem = menuItems[i];
			System.out.println(menuItem);
		}
		System.out.println("\n");
	}


	public void printMenu() {
		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
		Iterator dinerIterator = dinerMenu.createIterator();
		printMenu(pancakeIterator);
		printMenu(dinerIterator);

	}

	private void printMenu(Iterator iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = iterator.next();
			System.out.println(menuItem);
		}
	}
}

La clase de prueba final

import menu.DinerMenu;
import menu.PancakeHouseMenu;

public class Test
{
    public static void main(String[] args)
    {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();

        Waitress waitress=new Waitress(pancakeHouseMenu,dinerMenu);
        waitress.printMenu();
    }
}

El resultado es el mismo.

138 artículos originales publicados · elogiados 34 · 150,000 visitas

Supongo que te gusta

Origin blog.csdn.net/bbj12345678/article/details/105158838
Recomendado
Clasificación