Iterator(迭代器模式)

来源:互联网 发布:知乎发帖竟然封号 编辑:程序博客网 时间:2024/04/30 08:53

1、定义

           提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

2、结构图

            

3、协作角色

        Interator 定义访问遍历对象内部元素的接口

        ConcreteInterator 实现Interator接口,在遍历时跟踪当前位置。

       Aggregate 定义创建相应迭代器的接口

       ConcreteAggregate 实现创建相应迭代器的接口,返回创建的迭代器的实例。

4、适用性

       访问一个聚合对象内部元素而无需暴漏它的内部表示

        支持对象的各种遍历。

        为遍历不同的聚合结构提供一个统一的接口。

5、实例:

      1、需求(引用head first 设计模式的是个例子)。一个早餐店收购一家午餐店(and so on)。所以现在有两份菜单,加入一份按照数组方式实现,一份是按照队列方式实现,现在要实现一个服务员对象,可以轻松实现按照客户需要打印一份菜单。

      2、实现:

menu.h

   

#ifndef __MENU_H__#define __MENU_H__#define MENU_NAME_LEN16#define MENU_DESC_LEN64#define RET_SUCCESS0#define RET_FAIL(-1)#define IS_VEG1#define NOT_VEG0typedef struct menu_s{char name[MENU_NAME_LEN];char desc[MENU_DESC_LEN];int isVeg;double price;}menu_t;typedef enum {MENU_BF,MENU_LUNCH}MENU_TYPE;int menu_item_init(menu_t *item, char *name, char *desc, int isVeg, double price);char *menu_item_get_name(menu_t *item);char *menu_item_get_desc(menu_t *item);double menu_item_get_price(menu_t *item);int menu_item_get_isVeg(menu_t *item);#endif


menu.c

#include <stdio.h>#include <string.h>#include "menu.h"int menu_item_init(menu_t *item, char *name, char *desc, int isVeg, double price){if(NULL == item)return RET_FAIL;if((NULL != name)&&(strlen(name) < MENU_NAME_LEN))memcpy(item->name, name ,strlen(name));if((NULL != desc)&&(strlen(desc) < MENU_NAME_LEN))memcpy(item->desc, desc ,strlen(desc));item->isVeg = isVeg;item->price = price;return RET_SUCCESS;}char *menu_item_get_name(menu_t *item){if(NULL == item)return NULL;return item->name;}char *menu_item_get_desc(menu_t *item){if(NULL == item)return NULL;return item->desc;}double menu_item_get_price(menu_t *item){if(NULL == item)return 0;return item->price;}int menu_item_get_isVeg(menu_t *item){if(NULL == item)return 0;return item->isVeg;}

 

pancakeMenu.h

#ifndef __PANCAKEMENU_H__#define __PANCAKEMENU_H__int lunch_menu_init();menu_t* lunch_next();int lunch_hasNext();#endif


pancakeMenu.c

#include <stdio.h>#include <string.h>#include <stdlib.h>#include "menu.h"#include "pancakeMenu.h"typedef struct lunch_menu_s {menu_t lunch;struct lunch_menu_s *next;}lunch_menu_t;lunch_menu_t lunch_head;lunch_menu_t *lunch_cur;static int lunch_add_item(char *name, char *desc, int isVeg, double price){lunch_menu_t *item = NULL;item = (lunch_menu_t *)malloc(sizeof(lunch_menu_t));if(NULL == item){return RET_FAIL;}menu_item_init(&(item->lunch),name, desc, isVeg,price);item->next = lunch_head.next;lunch_head.next = item;return RET_SUCCESS;}int lunch_menu_init(){memset((void *)&lunch_head, 0, sizeof(lunch_menu_t));lunch_head.next = NULL;lunch_add_item("l1","this l1",IS_VEG,2.99);lunch_add_item("l2","this l2",IS_VEG,2.69);lunch_add_item("l3","this l3",NOT_VEG,7.99);lunch_add_item("l4","this l4",IS_VEG,3.99);lunch_cur = lunch_head.next;return RET_SUCCESS;}menu_t* lunch_next(){menu_t *menu = &lunch_cur->lunch;lunch_cur = lunch_cur->next;return menu;}int lunch_hasNext(){return !(lunch_cur == NULL);}


bfMenu.h

#ifndef __BFMENU_H__#define __BFMENU_H__int bf_menu_init();menu_t* bf_next();int bf_hasNext();#endif


 

bfMenu.c

#include <stdio.h>#include <string.h>#include "menu.h"#include "bfMenu.h"#define ARR_SIZE10typedef struct {menu_t breakfast[ARR_SIZE];int used[ARR_SIZE];int num;}bf_menu_t;bf_menu_t breakfast;int bf_cur = 0;static int bf_add_item(char *name, char *desc, int isVeg, double price){unsigned int index;unsigned int i;for(i = 0; i < ARR_SIZE; i++){if(breakfast.used[i] == 0){menu_item_init(&breakfast.breakfast[i],name, desc, isVeg,price);breakfast.used[i] = 1;breakfast.num++;return RET_SUCCESS;}}return RET_FAIL;}int bf_menu_init(){memset((void *)&breakfast, 0, sizeof(breakfast));bf_add_item("b1","this b1",IS_VEG,2.99);bf_add_item("b2","this b2",IS_VEG,2.69);bf_add_item("b3","this b3",NOT_VEG,7.99);bf_add_item("b4","this b4",IS_VEG,3.99);bf_cur = 0;return RET_SUCCESS;}menu_t* bf_next(){int cur = bf_cur;bf_cur++;return (&breakfast.breakfast[cur]);}int bf_hasNext(){return !(bf_cur == breakfast.num);}


iterator.h

#ifndef __ITERATOR_H__#define __ITERATOR_H__typedef struct {menu_t* (*next)();int (*hasNext)();}iterator_t;iterator_t *create_iterator(MENU_TYPE type);#endif


iterator.c

#include <stdio.h>#include <string.h>#include <stdlib.h>#include "menu.h"#include "iterator.h"#include "bfMenu.h"#include "pancakeMenu.h"iterator_t *create_iterator(MENU_TYPE type){iterator_t *iterator = NULL;iterator = (iterator_t *)malloc(sizeof(iterator_t));if(NULL == iterator){return NULL;}switch(type){case MENU_BF:bf_menu_init();iterator->hasNext = bf_hasNext;iterator->next = bf_next;break;case MENU_LUNCH:lunch_menu_init();iterator->hasNext = lunch_hasNext;iterator->next = lunch_next;break;default:break;}return iterator;}


client.c

#include <stdio.h>#include "menu.h"#include "iterator.h"int main(){iterator_t *iterator_bf = NULL;iterator_t *iterator_lunch = NULL;menu_t *item = NULL;iterator_bf = create_iterator(MENU_BF);printf("create bf %p\n",iterator_bf);if(NULL == iterator_bf){return 1;}while(iterator_bf->hasNext()){item = iterator_bf->next();printf("name %s desc %s\n",menu_item_get_name(item),menu_item_get_desc(item));}iterator_lunch = create_iterator(MENU_LUNCH);if(NULL == iterator_lunch){return 1;}while(iterator_lunch->hasNext()){item = iterator_lunch->next();printf("name %s desc %s\n",menu_item_get_name(item),menu_item_get_desc(item));}return 0;}

 

 

原创粉丝点击