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] */ //-------------------------------------
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] 请按任意键继续. . . */
**
常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。