行为型:六. 迭代器模式
迭代器模式是什么
迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
为什么用迭代器模式
当集合背后为复杂的数据结构, 且你希望对客户端隐藏其复杂性时(出于使用便利性或安全性的考虑),可以使用迭代器模式。迭代器封装了与复杂数据结构进行交互的细节,为客户端提供多个访问集合元素的简单方法。这种方式不仅对客户端来说非常方便,而且能避免客户端在直接与集合交互时执行错误或有害的操作, 从而起到保护集合的作用。
迭代器模式怎么实现
迭代器模式的主要思想是将集合背后的迭代逻辑提取至不同的名为迭代器的对象中。迭代器提供了一种方法用于在集合上进行迭代。
collection.go 集合
package iterator
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,
}
}
iterator.go 迭代器
package iterator
type iterator interface {
hasNext() bool
getNext() *user
}
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
}
example.go 客户端调用示例
package iterator
import "fmt"
func Example() {
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)
}
}
优点
- 单一职责原则。 通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
- 开闭原则。 你可实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
缺点
- 如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正。