设计模式之迭代器模式
来源:互联网 发布:mp3网络歌曲地址 编辑:程序博客网 时间:2024/06/05 19:24
一、模式动机
有很多种方法可以把对象堆起来成为一个集合(collection)。可以把它们放进数组、堆栈、列表或是散列表(Hashtable)中。如果想遍历这些对象而且无法窥视存储对象的方法,就需要迭代器模式。
二、模式定义
迭代器模式(Iterator Pattern)提供了一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。集合(collection)是指一群对象,其存储方式可以是各式各样的数据结构,例如:列表、数组等,有时候也被称为聚合(aggregate)。UML图如下:
迭代器模的角色有如下:
● 迭代器角色(Iterator):负责定义访问和遍历元素的接口。
● 具体迭代器角色(Concrete Iterator):实现迭代器的接口,并要记录遍历中的当前位置。
● 集合角色(Aggregate):负责定义创建具体迭代器角色的接口。
● 具体集合角色(Concrete Aggregate):实现创建具体迭代器角色的接口
三、模式示例
对象村的早餐店和午餐餐厅合并了,但是它们菜单使用不同数据结构表示,早餐店使用列表,午餐厅使用数组,如图代码所示。如何遍历每份菜单上的项目?
C++代码实现:
#include <string>#include <list>#include <iostream>using namespace std;//菜单项class MenuItem{public: MenuItem() { } MenuItem(string name, string description, bool vegetarian, double price) { name_ = name; description_ = description; vegetarian_ = vegetarian; price_ = price; } ~MenuItem() { } string GetName() const { return name_; } string GetDescripition() const { return description_; } bool IsVegetarian() const { return vegetarian_; } double GetPrice() const { return price_; }private: string name_; string description_; bool vegetarian_; double price_;};//迭代器基类 class Iterator{public: //是否有下一个菜单 virtual bool HasNext() = 0; //取下一个菜单 virtual MenuItem Next() = 0;};//煎饼屋餐单迭代器 class PancakeHouseMenuIterator : public Iterator{public: PancakeHouseMenuIterator(list<MenuItem> item) { items = item; iter = items.begin(); } MenuItem Next() { MenuItem menuItem = *iter; ++iter; return menuItem; } bool HasNext() { if (iter == items.end()) { return false; } else { return true; } }private: list<MenuItem> items; list<MenuItem>::const_iterator iter;};//午餐店餐单迭代器 class DinerMenuIterator : public Iterator{public: DinerMenuIterator(MenuItem* items[], int size) :position(0), size_(size) { this->items = items; position = 0; } MenuItem Next() { MenuItem menuItem = *(items[position]); position += 1; return menuItem; } bool HasNext() { if ((position >= size_) || (items[position] == NULL)) { return false; } else { return true; } }private: MenuItem** items; unsigned int size_; unsigned int position;};//餐单基类 class Menu{public: //创建迭代器 virtual Iterator* createIterator(){ throw std::exception("ERROR"); }};//煎饼屋菜单class PancakeHouseMenu :public Menu{public: PancakeHouseMenu(); ~PancakeHouseMenu(); void AddItem(string name, string description, bool vegetarian, double price) { MenuItem menuItem(name, description, vegetarian, price); menuItems_.push_back(menuItem); } list<MenuItem> GetMenuItems() { return menuItems_; } Iterator* createIterator(){ return new PancakeHouseMenuIterator(this->GetMenuItems()); }private: list<MenuItem> menuItems_;};PancakeHouseMenu::PancakeHouseMenu(){ AddItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99); AddItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99); AddItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49); AddItem("Waffles", "with you choice of blueberries or strawberries", true, 3.59);}PancakeHouseMenu::~PancakeHouseMenu(){}const int MAX_ITEMS = 6;class DinerMenu :public Menu{public: DinerMenu(); ~DinerMenu(); void AddItem(string name, string description, bool vegetarian, double price) { MenuItem* menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems >= MAX_ITEMS) { cout << "Sorry, menu is full! Can't add item to menu" << endl; } else { menuItems_[numberOfItems] = menuItem; numberOfItems += 1; } } MenuItem** GetMenuItems() { return menuItems_; } Iterator* createIterator() { return new DinerMenuIterator(GetMenuItems(), MAX_ITEMS); }private: int numberOfItems; MenuItem* menuItems_[MAX_ITEMS];};DinerMenu::DinerMenu() :numberOfItems(0){ for (unsigned int i = 0; i < MAX_ITEMS; i++) { menuItems_[i] = NULL; } AddItem("Vegetarian BLT", "(Fakin) Bacon with lettuce & tomato on whole wheat", true, 2.99); AddItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99); AddItem("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29); AddItem("Hotdog", "a hot dog, with saurkraut,relish,onions,topped with cheese", false, 3.05);}DinerMenu::~DinerMenu(){}class Waitess{public: Waitess(PancakeHouseMenu* pancake_house_menu, DinerMenu* diner_menu); ~Waitess(); void printMenus() { Iterator* pancake_iterator = pancake_house_menu_->createIterator(); Iterator* diner_iterator = diner_menu_->createIterator(); printMenu(pancake_iterator); cout << "+++++++++++++" << endl; printMenu(diner_iterator); }private: PancakeHouseMenu* pancake_house_menu_; DinerMenu* diner_menu_; void printMenu(Iterator* iteror) { while (iteror->HasNext()) { MenuItem menu_item = iteror->Next(); cout << menu_item.GetName() << endl; cout << menu_item.GetDescripition() << endl; cout << menu_item.GetPrice() << endl; } }};Waitess::Waitess(PancakeHouseMenu* pancake_house_menu, DinerMenu* diner_menu) :pancake_house_menu_(pancake_house_menu), diner_menu_(diner_menu){}Waitess::~Waitess(){}int _tmain(int argc, _TCHAR* argv[]){ PancakeHouseMenu* pancakeHouseMenu = new PancakeHouseMenu; DinerMenu* dinerMenu = new DinerMenu; Waitess waitess(pancakeHouseMenu, dinerMenu); waitess.printMenus(); system("pause"); return 0;}
运行结果:
四、分析总结
迭代器模式提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。另外,迭代器模式把元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所专注的事情上面,而不必去理会遍历的事情。
阅读全文
0 0
- 设计模式之迭代器模式
- 设计模式之 迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之--迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之-迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式 之 迭代器模式
- 设计模式 之 迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 洛谷
- 快速排序实现
- 主索引和二级索引区别,并创建一个二级索引
- SpringMVC详解(一)------入门实例
- tensorflow 学习笔记9 卷积神经网络(CNN)实现mnist手写识别
- 设计模式之迭代器模式
- Tomcat服务器环境配置
- Kanzi在汽车HMI领域的应用-Kanzi UI Solution
- springCloud微服务使用
- Hibernate导包
- CentOS6 快速安装oVirt及使用
- 【BUG记录】集群启动后,jps没有datanode,检查发现clusterid一致
- 并发和并行
- 嵌入式系统概论-1.2