Skip to content

Commit c836a85

Browse files
author
Jarry
committed
add iterator for c
1 parent 50c8626 commit c836a85

File tree

16 files changed

+516
-31
lines changed

16 files changed

+516
-31
lines changed

iterator-pattern/README.md

+111-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 【迭代器设计模式详解】Java/JS/Go/Python/TS不同语言实现
1+
# 【迭代器设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
22

33
# 简介
44
迭代器模式(Iterator Pattern),是一种结构型设计模式。给数据对象构建一套按顺序访问集合对象元素的方式,而不需要知道数据对象的底层表示。
@@ -18,7 +18,7 @@
1818
# UML
1919
<img src="../docs/uml/iterator-pattern.png">
2020

21-
# 代码
21+
# Java代码
2222

2323
## 迭代器抽象接口
2424
```java
@@ -63,7 +63,7 @@ public class ObjectIterator implements Iterator {
6363

6464
## 数据容器接口
6565
```java
66-
// 创建抽象容器接口,创建一个迭代器
66+
// Container.go 创建抽象容器接口,创建一个迭代器
6767
public interface Container {
6868
public Iterator createIterator();
6969
}
@@ -116,9 +116,117 @@ public class ObjectList implements Container {
116116

117117
// while循环迭代对象
118118
Iterator iter2 = objectList.createIterator();
119+
objectList.setObjects(new Integer[] { 3, 5, 7, 9, 11 });
119120
while (iter2.hasNext()) {
120121
System.out.println(iter2.next());
121122
}
122123
```
124+
125+
# Go代码
126+
127+
## 迭代器抽象接口
128+
```go
129+
// Iterator.go 迭代器抽象接口,提供next和hasNext方法
130+
type Iterator interface {
131+
HasNext() bool
132+
Next() string
133+
}
134+
```
135+
136+
## 具体迭代器
137+
```go
138+
// ObjectIterator.go 对象迭代器,实现了抽象迭代器的方法,聚合了对象列表
139+
type ObjectIterator struct {
140+
// 迭代器索引
141+
index int
142+
// 聚合了数据对象
143+
objectList *ObjectList
144+
}
145+
146+
func (o *ObjectIterator) HasNext() bool {
147+
if o.index < o.objectList.Size() {
148+
return true
149+
}
150+
return false
151+
}
152+
153+
func (o *ObjectIterator) Next() string {
154+
if o.HasNext() {
155+
// 返回数据对象提供的get方法,每访问一次下标增加1位
156+
item := o.objectList.Get(o.index)
157+
o.index += 1
158+
return item
159+
}
160+
return ""
161+
}
162+
```
163+
164+
## 数据容器接口
165+
```go
166+
// Container.go 创建抽象容器接口,创建一个迭代器
167+
type Container interface {
168+
CreateIterator() Iterator
169+
}
170+
```
171+
172+
## 具体数据对象
173+
```go
174+
// ObjectList.go 对象列表,是一种数据容器,可以创建一个迭代器
175+
type ObjectList struct {
176+
// 内部的数据结构
177+
objects []string
178+
}
179+
180+
func (o *ObjectList) CreateIterator() Iterator {
181+
fmt.Println("ObjectList::CreateIterator() [获取迭代器 ObjectIterator]")
182+
// 创建迭代器实例,绑定新建当前对象
183+
return &ObjectIterator{
184+
objectList: o,
185+
}
186+
}
187+
188+
func (o *ObjectList) SetObjects(objects []string) {
189+
o.objects = objects
190+
}
191+
192+
func (o *ObjectList) GetObjects() []string {
193+
return o.objects
194+
}
195+
196+
func (o *ObjectList) Size() int {
197+
return len(o.objects)
198+
}
199+
200+
func (o *ObjectList) Get(index int) string {
201+
return o.objects[index]
202+
}
203+
```
204+
205+
## 测试调用
206+
```go
207+
/*
208+
* 迭代器模式是给数据容器创建单独的迭代器,用来遍历里面的数据对象
209+
* 数据容器和迭代器相互关联,外部通过迭代器来访问数据容器
210+
* 通过这种方式由迭代器类来负责数据遍历,这样可以做到不暴露集合的内部结构
211+
*/
212+
213+
int i = 0;
214+
ObjectList objectList = new ObjectList();
215+
objectList.setObjects(new String[] { "Thomas", "Merry", "Jack", "Tony", "Jerry", "Joey" });
216+
// for循环迭代对象
217+
for (Iterator iter = objectList.createIterator(); iter.hasNext();) {
218+
String name = (String) iter.next();
219+
System.out.println("objectList[" + i + "] = " + name);
220+
i++;
221+
}
222+
223+
// while循环迭代对象
224+
Iterator iter2 = objectList.createIterator();
225+
objectList.setObjects(new Integer[] { 3, 5, 7, 9, 11 });
226+
while (iter2.hasNext()) {
227+
System.out.println(iter2.next());
228+
}
229+
```
230+
123231
## 更多语言版本
124232
不同语言实现设计模式:[https://github.com/microwind/design-pattern](https://github.com/microwind/design-pattern)

iterator-pattern/c/src/container.c

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "func.h"
2+
3+
// 抽象容器struct,定义在head,可选

iterator-pattern/c/src/func.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <stdio.h>
2+
#include <ctype.h>
3+
#include <stdlib.h>
4+
#include <stdbool.h>
5+
#include <string.h>
6+
7+
// 创建抽象容器接口,创建一个迭代器,可选
8+
typedef struct Container
9+
{
10+
void (*set_objects)(struct Container *, char **objects, int);
11+
char **(*get_objects)(struct Container *);
12+
char *(*get)(struct Container *, int index);
13+
int length;
14+
// 字符串数组
15+
char **objects;
16+
struct Iterator *(*create_iterator)(struct Container *object_list);
17+
} Container;
18+
19+
// 数据对象,是一种数据容器,实现了数据容器接口,可以创建一个迭代器
20+
typedef struct ObjectList
21+
{
22+
void (*set_objects)(struct ObjectList *, char **objects, int);
23+
char **(*get_objects)(struct ObjectList *);
24+
char *(*get)(struct ObjectList *, int index);
25+
int length;
26+
// 字符串数组
27+
char **objects;
28+
struct Iterator *(*create_iterator)(struct ObjectList *object_list);
29+
} ObjectList;
30+
ObjectList *object_list_constructor();
31+
32+
// 迭代器抽象接口,提供next和hasNext方法
33+
typedef struct Iterator
34+
{
35+
// 迭代器索引
36+
int index;
37+
// 数据对象数组
38+
struct ObjectList *object_list;
39+
bool (*has_next)(struct Iterator *);
40+
char *(*next)(struct Iterator *);
41+
} Iterator;
42+
43+
// 对象迭代器,实现了抽象迭代器的方法,聚合了数据对象
44+
typedef struct ObjectIterator
45+
{
46+
// 迭代器索引
47+
int index;
48+
// 数据对象数组
49+
struct ObjectList *object_list;
50+
bool (*has_next)(struct Iterator *);
51+
char *(*next)(struct Iterator *);
52+
} ObjectIterator;
53+
ObjectIterator *object_iterator_constructor(ObjectList *object_list);

iterator-pattern/c/src/iterator.c

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "func.h"
2+
#include <stdarg.h>
3+
4+
// 迭代器抽象接口,约定next和has_next方法,定义在head
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "func.h"
2+
3+
bool has_next(Iterator *iter)
4+
{
5+
if (iter->index < iter->object_list->length)
6+
{
7+
return true;
8+
}
9+
return false;
10+
}
11+
12+
char *next(Iterator *iter)
13+
{
14+
if (iter->has_next(iter))
15+
{
16+
// 返回数据对象提供的get方法,每访问一次下标增加1位
17+
char *item = iter->object_list->get(iter->object_list, iter->index);
18+
iter->index += 1;
19+
return item;
20+
}
21+
return NULL;
22+
}
23+
24+
// 对象迭代器,实现了抽象迭代器的方法,聚合了数据对象
25+
ObjectIterator *object_iterator_constructor(ObjectList *object_list)
26+
{
27+
printf("\r\n object_iterator_constructor() [构建容器迭代器]");
28+
ObjectIterator *iter = (ObjectIterator *)malloc(sizeof(ObjectIterator));
29+
iter->object_list = object_list;
30+
iter->index = 0;
31+
iter->next = &next;
32+
iter->has_next = &has_next;
33+
return iter;
34+
}

iterator-pattern/c/src/object_list.c

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "func.h"
2+
3+
void set_objects(ObjectList *object_list, char **objects, int len)
4+
{
5+
object_list->length = len;
6+
object_list->objects = objects;
7+
}
8+
9+
char **get_objects(ObjectList *object_list)
10+
{
11+
return object_list->objects;
12+
}
13+
14+
char *get(ObjectList *object_list, int index)
15+
{
16+
return object_list->objects[index];
17+
}
18+
19+
Iterator *create_iterator(ObjectList *object_list)
20+
{
21+
// 创建迭代器实例,绑定新建当前对象
22+
return (Iterator *)object_iterator_constructor(object_list);
23+
}
24+
25+
// 数据对象,是一种具体的数据容器,实现了数据容器抽象接口,可以创建一个迭代器
26+
ObjectList *object_list_constructor()
27+
{
28+
printf("\r\n object_list_constructor() [构建数据容器对象]");
29+
Container *obj = (Container *)malloc(sizeof(Container));
30+
ObjectList *list = (ObjectList *)obj;
31+
list->objects = NULL;
32+
list->length = 0;
33+
list->set_objects = &set_objects;
34+
list->get_objects = &get_objects;
35+
list->get=&get;
36+
list->create_iterator = &create_iterator;
37+
return list;
38+
}
+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
// 简单版C语言迭代器模式,自己构建List数据类型
5+
6+
// 数据结构,这里使用链表作为示例
7+
struct List
8+
{
9+
char *data;
10+
struct List *next;
11+
};
12+
13+
// 迭代器结构体
14+
struct Iterator
15+
{
16+
struct List *current;
17+
int (*has_next)(struct Iterator *); // 判断是否还有下一个元素
18+
char *(*next)(struct Iterator *, char **); // 获取下一个元素
19+
};
20+
21+
// 判断是否还有下一个元素
22+
int has_next(struct Iterator *iter)
23+
{
24+
return iter->current != NULL;
25+
}
26+
27+
// 获取下一个元素
28+
char *next(struct Iterator *iter, char **value)
29+
{
30+
if (iter->current == NULL)
31+
{
32+
return NULL;
33+
}
34+
*value = iter->current->data;
35+
iter->current = iter->current->next;
36+
return *value;
37+
}
38+
39+
// 初始化迭代器
40+
void create_iterator(struct Iterator *iter, struct List *head)
41+
{
42+
iter->current = head;
43+
iter->has_next = &has_next;
44+
iter->next = &next;
45+
}
46+
47+
// 遍历链表
48+
void iterate_list(struct List *head)
49+
{
50+
struct Iterator iter;
51+
char *value;
52+
create_iterator(&iter, head);
53+
while (iter.has_next(&iter))
54+
{
55+
iter.next(&iter, &value);
56+
printf("\r\n %s ", value);
57+
}
58+
printf("\n");
59+
}
60+
61+
int main()
62+
{
63+
printf("test start:\r\n");
64+
// 构造一个链表
65+
struct List *head = (struct List *)malloc(sizeof(struct List));
66+
head->data = "Tom";
67+
head->next = (struct List *)malloc(sizeof(struct List));
68+
head->next->data = "Jerry";
69+
head->next->next = (struct List *)malloc(sizeof(struct List));
70+
head->next->next->data = "Max";
71+
head->next->next->next = NULL;
72+
73+
// 使用迭代器遍历链表
74+
iterate_list(head);
75+
76+
// 释放链表内存
77+
while (head != NULL)
78+
{
79+
struct List *temp = head;
80+
head = head->next;
81+
free(temp);
82+
}
83+
84+
return 0;
85+
}
86+
87+
/**
88+
jarry@jarrys-MacBook-Pro c % gcc test/simple_iterator.c
89+
jarry@jarrys-MacBook-Pro c % ./a.out
90+
test start:
91+
92+
Tom
93+
Jerry
94+
Max
95+
*/

0 commit comments

Comments
 (0)