C++设计模式十一--IteratorPattern(迭代器模式)
来源:互联网 发布:淘宝店铺流量来源查询 编辑:程序博客网 时间:2024/06/05 19:42
定义
迭代器模式提供一种方法顺序访问一个聚合(集合)对象中的各个元素,而又不暴露其内部的表示。
要点
1.迭代器模式提供一种方法,可以顺序访问一个聚合(集合)对象中的元素,而又不用知道内部是如何表示的。
2.迭代器将遍历聚合(集合)的工作封装进一个对象中。
3.当使用迭代器时,我们依赖聚合(集合)提供遍历。
4.迭代器提供了一个通用的接口,让我们遍历聚合(集合)的项,当我们编码使用聚合(集合)的项时,就可以使用多态机制。
5.迭代器模式把元素的遍历交给迭代器,而不是聚合(集合)对象。这不仅让聚合(集合)的接口和实现变得更简洁,也可以让聚合(集合)更专注它所应该专注的事情上面,而不必去理会遍历的事情。
类图
Aggregate:聚合(集合)接口,这对客户代码是很方便的,将客户代码从集合对象的实现解耦了。
ConcreteAggregate:具体聚合(集合)持有一个对象的集合,并实现一个方法(createIterator()),利用此方法返回集合的的迭代器。
Iterator:所有迭代器都必须实现的接口。它包含了一些方法,利用这些方法可以在集合元素之间游走。
ConcreteIterator:具体迭代器负责管理目前遍历的位置。
设计原则
单一责任:一个类应该只有一个引起变化的原因。
1.修改一个类的代码的原因应该只有一个。
2.这个原则告诉我们将一个责任只指派给一个类。
3.当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚。
示例
下面通过实现两种不同餐厅菜单的迭代器,给服务员提供一个统一的遍历接口。
Menu.h(Aggregate)
#ifndef MENU_H#define MENU_H#include "Iterator.h"namespace Iterator{class Menu{public: Menu(){} virtual ~Menu(){} virtual Iterator* createIterator() = 0;};}#endif
MenuItem.h
#ifndef MENUITEM_H#define MENUITEM_H#include <iostream>#include <string>namespace Iterator{using std::cout;using std::endl;using std::string;class MenuItem{public: MenuItem(string n, int p): name(n), price(p) { } ~MenuItem(){} string getName() { return name; } int getPrice() { return price; } void print() { cout << getName() << ": " << getPrice() << endl; }private: string name; int price;};}#endif
Breakfast.h (ConcreteAggregate)
#ifndef BREAKFAST_H#define BREAKFAST_H#include <iostream>#include <string>#include <vector>#include "Menu.h"#include "MenuItem.h"#include "Iterator.h"namespace Iterator{using std::cout;using std::endl;using std::string;using std::vector;class Breakfast: public Menu{public: Breakfast() { MenuItem *m1 = new MenuItem("Egg", 3); MenuItem *m2 = new MenuItem("Bread", 5); MenuItem *m3 = new MenuItem("Milk", 1); addMenuItem(m1); addMenuItem(m2); addMenuItem(m3); } ~Breakfast() { // need free memory } void addMenuItem(MenuItem *mi) { menu.push_back(mi); } Iterator *createIterator() { return new BreakfastIterator(menu); }private: vector<MenuItem *> menu;};}#endif
Diner.h (ConcreteAggregate)
#ifndef DINER_H#define DINER_H#include <iostream>#include <string>#include "Menu.h"#include "MenuItem.h"#include "Iterator.h"namespace Iterator{using std::cout;using std::endl;using std::string;class Diner: public Menu{public: Diner(): menuCount(0) { MenuItem *m1 = new MenuItem("Meat", 10); MenuItem *m2 = new MenuItem("Fish", 20); MenuItem *m3 = new MenuItem("Steak", 50); addMenuItem(m1); addMenuItem(m2); addMenuItem(m3); } ~Diner() { // need free memory } void addMenuItem(MenuItem *mi) { menu[menuCount] = mi; menuCount++; } Iterator *createIterator() { return new DinerIterator(menu, menuCount); }private: MenuItem* menu[10]; int menuCount;};}#endif
Iterator.h
#ifndef ITERATOR_H#define ITERATOR_H#include <vector>#include "MenuItem.h"namespace Iterator{using std::vector;// 迭代器接口class Iterator{public: Iterator(){} virtual ~Iterator(){} virtual int hasNext() = 0; virtual MenuItem* next() = 0;};// 午餐迭代器 (ConcreteIterator)class DinerIterator: public Iterator{public: DinerIterator(MenuItem *d[], int c): menuList(d), count(c), index(0) {} ~DinerIterator(){} int hasNext() { return index < count; } MenuItem* next() { MenuItem *m = menuList[index]; index++; return m; }private: MenuItem **menuList; int count; int index;};// 早餐迭代器 (ConcreteIterator)class BreakfastIterator: public Iterator{public: BreakfastIterator(vector<MenuItem*> &mv) { menuVectorIterator = mv.begin(); end = mv.end(); } ~BreakfastIterator(){} int hasNext() { return (int)(menuVectorIterator != end); } MenuItem* next() { MenuItem *m = *(menuVectorIterator); menuVectorIterator++; return m; }private: vector<MenuItem *>::const_iterator menuVectorIterator; vector<MenuItem *>::const_iterator end;};}#endif
Waitress.h (Client)
#ifndef WAITRESS_H#define WAITRESS_H#include "Menu.h"#include "Iterator.h"#include <iostream>namespace Iterator{using std::cout;using std::endl;class Waitress{private: Menu* m_pancakeHouseMenu; Menu* m_dinerMenu;private: void printMenu(Iterator* iterator) { while (iterator->hasNext()) { iterator->next()->print(); } }public: Waitress(Menu* pancakeHouseMenu, Menu* dinerMenu) { m_pancakeHouseMenu = pancakeHouseMenu; m_dinerMenu = dinerMenu; } ~Waitress() {} void printMenu() { Iterator *pancakeIterator = m_pancakeHouseMenu->createIterator(); Iterator *dinerIterator = m_dinerMenu->createIterator(); cout << "\nMenu\n========\nbreakfast:" << endl; printMenu(pancakeIterator); cout << "\nLunch:" << endl; printMenu(dinerIterator); delete pancakeIterator; delete dinerIterator; }}; }#endif
main.cpp
#include "Iterator.h"#include "Breakfast.h"#include "Diner.h"#include "Waitress.h"using namespace Iterator;int main(){ Breakfast *b = new Breakfast(); Diner *d = new Diner(); Waitress* waitress = new Waitress(b, d); waitress->printMenu(); delete b; delete d; return 0;}
Makefile
CXX = g++CFLAGS = -WallLDFLAGS = target = ressrcs = main.cppobjs = $(srcs:.cpp=.o)headers = $(wildcard *.h).PHONY: allall: $(target)$(target): $(objs) $(headers) FORCE $(CXX) $(LDFLAGS) -o $(target) $(objs) -rm -f *.o ./$(target)$(objs):%.o:%.cpp $(CXX) $(CFLAGS) -c -o $@ $<.PHONY: FORCEFORCE: clean: rm -f $(target) *.o
测试
测试结果如下图所示:
- C++设计模式十一--IteratorPattern(迭代器模式)
- 设计模式(c++)笔记之十一(Facade模式)
- Java设计模式(十一)
- 行为型:设计模式之迭代器模式(二十一)
- C++设计模式(十一) strategy模式
- 设计模式 (十一)桥模式(birdge)
- 设计模式 (十一)桥模式(birdge)
- 设计模式 (十一)桥模式(birdge)
- 设计模式(十一)-观察者模式
- 设计模式(十一)策略模式
- Java设计模式(十一)----组合模式
- 设计模式(二十一)---组合模式
- 设计模式(十一)抽象工厂模式
- java设计模式(十一)--状态模式
- 设计模式(十一)策略模式
- 设计模式(十一)策略模式
- 设计模式(十一)外观模式
- Android设计模式(十一)-观察者模式
- 加载页面时 lygrid 默认选中
- 最小生成树:普里姆算法.c++
- 面试简历可以用到的经典
- 手把手教你搭建SpringMVC
- Image
- C++设计模式十一--IteratorPattern(迭代器模式)
- spark上部署微服务
- CentOS安装strongLoop
- 最全的mysql学习笔记
- SpringMVC
- SOAP webserivce 和 RESTful webservice 对比及区别
- 【计网】网络层详解(下)
- MyEclipse中创建maven web项目
- docker+svn+maven+tomcat一键部署项目