HeadFirst设计模式-迭代器模式

 

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

 

 

 

Java例子

package i_IteratorPattern_CompositePattern;

import java.util.Iterator;

public interface Menu {
    
    Iterator createIterator();

}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

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

/**
 * 煎饼屋菜单
 * 使用的是ArrayList存储
 */
public class PancakeHouseMenu implements Menu {
    
    ArrayList menuItems;
    
    public PancakeHouseMenu() {
        menuItems = new ArrayList();
        addItenm("Item1","Description1",true,2.99);
        addItenm("Item2","Description2",true,2.19);
        addItenm("Item3","Description3",false,3.49);
    }

    private void addItenm(String name, String description, boolean vegetarian, double price) {
        MenuItem item = new MenuItem(name,description,vegetarian,price);
        menuItems.add(item);
        
    }

    @Override
    public Iterator createIterator() {
        //return new PancakeHouseMenuIterator(menuItems);
        //或者 
        return menuItems.iterator();
    }

}


//-------------------------------------
package i_IteratorPattern_CompositePattern;

import java.util.Iterator;

/**
 * 午餐
 * 使用 数组 保存数据
 */
public class DinerMemu implements Menu {
    static final int MAX_ITEMS = 6;
    int numberOfItems = 0;
    MenuItem[] menuItems;
    
    public DinerMemu() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItenm("Item11","Description11",true,2.99);
        addItenm("Item21","Description21",true,2.19);
        addItenm("Item31","Description31",false,3.49);
    }

    private void addItenm(String name, String description, boolean vegetarian, double price) {
        MenuItem item = new MenuItem(name,description,vegetarian,price);
        if(numberOfItems >= MAX_ITEMS) {
            System.out.println("Sorry, menu is full! Can not add item to menu.");
        }else {
            menuItems[numberOfItems] = item;
            numberOfItems++;
        }
        
    }
    
    @Override
    public Iterator createIterator() {
        return new DinerMenuIterator(menuItems);
    }

}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

public class MenuItem {
    private String name;
    private String description;
    private boolean vegetarian;
    private double price;
    public MenuItem(String name, String description, boolean vegetarian, double price) {
        super();
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public boolean isVegetarian() {
        return vegetarian;
    }
    public void setVegetarian(boolean vegetarian) {
        this.vegetarian = vegetarian;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "MenuItem [name=" + name + ", description=" + description + ", vegetarian=" + vegetarian + ", price="
                + price + "]";
    }
    
    
}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

import java.util.Iterator;

public class DinerMenuIterator implements Iterator {
    
    MenuItem[] items;
    int position = 0;
    
    public DinerMenuIterator(MenuItem[] items) {
        this.items = items;
    }

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

    @Override
    public Object next() {
        MenuItem menuItem = items[position];
        position++;
        return menuItem;
    }

    @Override
    public void remove() {
        if(position <=0) {
            throw new IllegalStateException("You can't remove an item until you've done at least one next().");
        }
        //position-1 是当前位置。因为执行了一次next()
        if(items[position-1] != null) {
            for (int i = position-1; i < items.length-1; i++) {
                items[i] = items[i+1];
            }
            items[items.length-1] = null;
        }
    }
}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

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

public class PancakeHouseMenuIterator implements Iterator {
    
    ArrayList items;
    Iterator it;
    
    public PancakeHouseMenuIterator(ArrayList items) {
        this.items = items;
        it = items.iterator();
    }

    @Override
    public boolean hasNext() {
        return it.hasNext();
    }

    @Override
    public Object next() {
        return it.next();
    }
    
    @Override
    public void remove() {
        it.remove();
    }

}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

import java.util.Iterator;

public class Waitress {
    
    PancakeHouseMenu phm;
    DinerMemu dm;
    
    public Waitress(PancakeHouseMenu pancakeHouseMenu,DinerMemu dinerMemu) {
        phm = pancakeHouseMenu;
        dm = dinerMemu;
    }
    
    public void printMenu() {
        Iterator pIter = phm.createIterator();
        Iterator dIter = dm.createIterator();
        System.out.println("Menu\n-----\nBreakfast");
        printMenu(pIter);
        System.out.println("\nLunch");
        printMenu(dIter);
    }

    //使用一种方法遍历俩个不同存储方式的类
    private void printMenu(Iterator it) {
        while(it.hasNext()) {
            MenuItem m = (MenuItem) it.next();
            System.out.println(m);
        }
        
    }

}

//-------------------------------------
package i_IteratorPattern_CompositePattern;

public class TestDemo {

    public static void main(String[] args) {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMemu dinerMemu = new DinerMemu();
        Waitress waitress = new Waitress(pancakeHouseMenu, dinerMemu);
        waitress.printMenu();

    }

}
/*
Menu
-----
Breakfast
MenuItem [name=Item1, description=Description1, vegetarian=true, price=2.99]
MenuItem [name=Item2, description=Description2, vegetarian=true, price=2.19]
MenuItem [name=Item3, description=Description3, vegetarian=false, price=3.49]

Lunch
MenuItem [name=Item11, description=Description11, vegetarian=true, price=2.99]
MenuItem [name=Item21, description=Description21, vegetarian=true, price=2.19]
MenuItem [name=Item31, description=Description31, vegetarian=false, price=3.49]

 */
//-------------------------------------
View Code

 

 C++例子

#pragma once

#include "IteratorMenu.h"
#include "MenuItem.h"

class Menu
{
public:

    Menu()
    {
    }

    virtual ~Menu()
    {
    }

    virtual IteratorMenu* createIterator() = 0;
};

//------------------------------
#pragma once
#include "Menu.h"
#include <vector>
#include "PancakeHouseMenuIterator.h"
using namespace std;

class PancakeHouseMenu : public Menu
{
    vector<MenuItem*> menuItems;
    IteratorMenu* itr;
public:

    PancakeHouseMenu()
    {
        itr = nullptr;
        addItem("Item1", "Description1", true, 2.99);
        addItem("Item2", "Description2", true, 2.19);
        addItem("Item3", "Description3", false, 3.49);
    }

    virtual ~PancakeHouseMenu()
    {
        for (auto it = menuItems.begin(); it != menuItems.end(); ++it){
            delete (*it);
        }
        menuItems.clear();
        delete itr;
    }

    virtual IteratorMenu* createIterator()
    {
        itr = new PancakeHouseMenuIterator(menuItems);
        return itr;
    }
private:
    void addItem(string name, string description, bool vegetarian, double price) {
        MenuItem* item = new MenuItem(name, description, vegetarian, price);
        menuItems.push_back(item);
    }
};

//------------------------------
#pragma once
#include "Menu.h"
#include <vector>
#include <iostream>
#include "DinerMenuIterator.h"

using namespace std;

class DinerMenu : public Menu
{
    static const int MAX_ITEMS = 6;
    int numberOfItems = 0;
    MenuItem* menuItems[MAX_ITEMS];
    DinerMenuIterator* itr=0;
public:

    DinerMenu()
    {
        for (int i = 0; i < MAX_ITEMS; ++i){
            menuItems[i] = nullptr;
        }
        itr = nullptr;
        addItem("Item11", "Description11", true, 2.99);
        addItem("Item21", "Description21", true, 2.19);
        addItem("Item31", "Description31", false, 3.49);
    }

    virtual ~DinerMenu()
    {
        for (int i = 0; i < MAX_ITEMS; ++i){
            MenuItem* tt = menuItems[i];
            delete tt;
            tt = nullptr;
        }
        delete itr;
        itr = nullptr;
    }

    virtual IteratorMenu* createIterator()
    {
        itr = new DinerMenuIterator(menuItems, MAX_ITEMS);
        return itr;
    }
private:
    void addItem(string name, string description, bool vegetarian, double price) {
        MenuItem* item = new MenuItem(name, description, vegetarian, price);
        if (numberOfItems >= MAX_ITEMS) {
            cout << ("Sorry, menu is full! Can not add item to menu.");
        }
        else {
            menuItems[numberOfItems] = item;
            numberOfItems++;
        }
    }
};

//------------------------------
#pragma once
#include "MenuItem.h"

class IteratorMenu
{
public:

    IteratorMenu()
    {
    }

    virtual ~IteratorMenu()
    {
    }

    virtual bool hasNext() = 0;

    virtual MenuItem next() = 0;
};

//------------------------------
#pragma once
#include "PancakeHouseMenu.h"
#include "MenuItem.h"
#include "IteratorMenu.h"

class PancakeHouseMenuIterator : public IteratorMenu
{
    vector<MenuItem*> items;
    int pos = 0;
public:

    PancakeHouseMenuIterator(vector<MenuItem*> items)
        : items(items)
    {
        //cout << &(items[0]) << "\n";
        //cout << &(this->items[0]) << "\n";
    }

    virtual ~PancakeHouseMenuIterator()
    {
    }

    virtual bool hasNext()
    {
        if (pos >= items.size()){
            return false;
        }
        return true;
    }

    virtual MenuItem next()
    {
        return *(items[pos++]);
    }
};

//------------------------------
#pragma once
#include "IteratorMenu.h"
#include "Menu.h"
class DinerMenuIterator : public IteratorMenu
{
    MenuItem** items;
    const int itemsLen;
    int position = 0;
public:

    DinerMenuIterator(MenuItem* menuItems[], int len)
        : items(menuItems)
        , itemsLen(len)
    {
    }

    virtual ~DinerMenuIterator()
    {
    }

    virtual bool hasNext()
    {
        if (position < 0 || position >= itemsLen || nullptr == items[position])
            return false;
        return true;
    }

    virtual MenuItem next()
    {
        MenuItem menuItem = *(items[position]);
        position++;
        return menuItem;
    }
};

//------------------------------
#pragma once
#include "IteratorMenu.h"
#include "PancakeHouseMenu.h"
#include "DinerMenu.h"
#include <iostream>
using namespace std;



class Waitress
{
    PancakeHouseMenu* phm;
    DinerMenu* dm;
public:

    Waitress(PancakeHouseMenu* pancakeHouseMenu, DinerMenu* dinerMemu)
        : phm(pancakeHouseMenu)
        , dm(dinerMemu)
    {
    }

    virtual ~Waitress()
    {
    }

    void printMenu() {
        IteratorMenu* pIter = phm->createIterator();
        IteratorMenu* dIter = dm->createIterator();
        cout << ("Menu\n-----\nBreakfast");
        printMenu(*pIter);
        cout <<("\nLunch");
        printMenu(*dIter);
    }
private:
    //使用一种方法遍历俩个不同存储方式的类
    void printMenu(IteratorMenu& it) {
        while (it.hasNext()) {
            MenuItem m = (MenuItem)it.next();
            cout << m.toString() << "\n";
        }

    }
};
//------------------------------
#include <iostream>

#include "DinerMenu.h"
#include "Waitress.h"
using namespace std;



void testVector(){
    vector<int> v1;
    int a = 1;
    v1.push_back(a);
    a = 2;
    v1.push_back(a);
    vector<int> v2(v1);

    cout << v1[0] << endl;
    cout << v2[0] << endl;
    cout << &v1[0] << endl;
    cout << &v2[0] << endl;
    printf("%08X\n%08X\n", &v1[0], &v2[0]);
}

int main(){

    //testVector();

    PancakeHouseMenu p;
    DinerMenu d;
    Waitress waitress(&p, &d);
    waitress.printMenu();
    return 0;
}
/*
Menu
-----
BreakfastMenuItem [name=Item1, description=Description1, vegetarian=true, price=2.990000]
MenuItem [name=Item2, description=Description2, vegetarian=true, price=2.190000]
MenuItem [name=Item3, description=Description3, vegetarian=false, price=3.490000]

LunchMenuItem [name=Item11, description=Description11, vegetarian=true, price=2.990000]
MenuItem [name=Item21, description=Description21, vegetarian=true, price=2.190000]
MenuItem [name=Item31, description=Description31, vegetarian=false, price=3.490000]
请按任意键继续. . .
*/
View Code

 

 

 

 

**

posted @ 2022-12-01 18:11  htj10  阅读(12)  评论(0编辑  收藏  举报
TOP