迭代器模式:也叫作游标模式,能在不暴露复杂数据结构内部细节的情况下遍历其中所有的元素。在迭代器的帮助下, 客户端可以用一个迭代器接口以相似的方式遍历不同集合中的元素。
当集合背后为复杂的数据结构,且希望对客户端隐藏其复杂性时 (出于使用便利性或安全性的考虑),或希望代码能够遍历不同的甚至是无法预知的数据结构 可以使用迭代器模式
- Iterator 接口: 这个接口会定义一些基础的操作函数,如
hasNext()
或getNext()
等。通过名称就可以看出,这些方法可以帮助我们执行遍历集合、重启迭代等操作。 - Collection 接口: 这个接口代表了要被遍历的集合。在这个接口里定义了一个
createIterator
方法,该方法会返回一个Iterator
的实例。 - Concrete Iterator:
Iterator
接口的具体实现类。 - Concrete Collection:
Collection
接口的具体实现类。 - 客户端 Client:通过集合和迭代器的接口与两者进行交互。 这样一来客户端无需与具体类进行耦合, 允许同一客户端代码使用各种不同的集合和迭代器。
迭代器接口
type Iterator interface {
hasNext() bool
getNext() *User
}
集合接口
type Collection interface {
createIterator() Iterator
}
用户类
type User struct {
name string
age int
}
用户集合数据结构
type UserCollection struct {
users []*User
}
// 实现集合接口
func (u *UserCollection) createIterator() Iterator {
return &UserIterator{
users: u.users,
}
}
实现迭代器接口
type UserIterator struct {
index int
users []*User
}
func (u *UserIterator) hasNext() bool {
if u.index < len(u.users) {
return true
}
return false
}
func (u *UserIterator) getNext() *User {
if u.hasNext() {
user := u.users[u.index]
u.index++
return user
}
return nil
}
main函数
func main() {
user1 := &User{
name: "a",
age: 30,
}
user2 := &User{
name: "b",
age: 20,
}
userCollection := &UserCollection{
users: []*User{user1, user2},
}
iterator := userCollection.createIterator()
for iterator.hasNext() {
user := iterator.getNext()
fmt.Printf("User is %+v\n", user)
}
}
结果
User is &{name:a age:30}
User is &{name:b age:20}
迭代器模式在平时编程的时候使用的并不多,像Java、C#编程时都自带了迭代器模式的实现,也支持实现语言内置的Iterator
接口来给自定义集合创建迭代器。