Iterator is a behavioral design pattern that lets you traverse elements of a collection without exposing its underlying representation (list, stack, tree, etc.).
type MenuItem struct {
Name string
Desc string
Vegetarian bool
Price float64
}
type PancakeHouseMenu struct {
Items list.List
}
func NewPackeHourseMenu() *PancakeHouseMenu {
p := &PancakeHouseMenu{}
p.Add("K&B's Pancake Breakfast", "Pancakes with scrambled eggs and toast", true, 2.99)
p.Add("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99)
p.Add("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29)
p.Add("Hotdog", "A hot dog, with sauerkraut, relish, onions, topped with cheese", false, 3.05)
return p
}
func (p *PancakeHouseMenu) Add(name, desc string, veg bool, price float64) {
m := &MenuItem{
Name: name,
Desc: desc,
Vegetarian: veg,
Price: price,
}
p.Items.PushBack(m)
}
type DinerMenu struct {
Items []*MenuItem
}
func NewDinerMenu() *DinerMenu {
d := &DinerMenu{}
d.Add("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99)
d.Add("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99)
d.Add("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29)
d.Add("Hotdog", "A hot dog, with sauerkraut, relish, onions, topped with cheese", false, 3.05)
return d
}
func (d *DinerMenu) Add(name, desc string, veg bool, price float64) {
m := &MenuItem{
Name: name,
Desc: desc,
Vegetarian: veg,
Price: price,
}
d.Items = append(d.Items, m)
}
from refactoring.guru:
迭代器模式的主要功能时在不暴露内部数据结构(list, array, tree...)的情况下提供一种遍历的方法。 不然每种数据结构在client都要实现以下,比如这种:
如果使用 iterator模式就会是这样的:
这就将大大的减少了使用方的心智负担(也为未来的扩展带来了方便)。下面就来看下具体的实现。
我们有以下的基础类:
如果这样写我们就会暴露太多内部的实现给client侧, 在clent测又要适配各种数据结构的遍历,为了实现迭代器模式,需要添加以下的代码:
在这种模式下新增一个Menu或者更换内部的实现方式就方便很多了。
iterator in real world
在goalng中迭代器模式最常见就是range 操作,虽然不是一个显示的迭代器模式, 但是range支持操作在各种collection上,所以是一个广义的迭代器模式。