迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露结构的底层表示和细节。
在以下情形,考虑使用迭代器模式:
- 需要访问组合对象的内容,而又不暴露其内部表示
- 需要通过多种方式遍历组合对象
- 需要提供一个统一的接口,用来遍历各种类型的组合对象
迭代器模式涉及到以下几个角色:
- 抽象迭代器(Iterator)角色:此抽象角色定义出遍历元素所需的接口。
- 具体迭代器(ConcreteIterator)角色:此角色实现了Iterator接口,并保持迭代过程中的游标位置。
- 聚集(Aggregate)角色:此抽象角色给出创建迭代器(Iterator)对象的接口。
- 具体聚集(ConcreteAggregate)角色:实现了创建迭代器(Iterator)对象的接口,返回一个合适的具体迭代器实例。
- 客户端(Client)角色:持有对聚集及其迭代器对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除。
UML类图
代码示例
定义迭代器接口和聚集角色:
1 2 3 4 5 6 7 8 9 10
| //迭代器接口 protocol Iterator{ func hasNext() -> Bool func next() -> AnyObject }
//需要使用迭代器的集合类型需要实现Container,返回一个迭代器对象 protocol Container { func makeIterator() -> Iterator }
|
定义书和书架类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Book { var name: String var author: String init(name: String, author: String) { self.name = name self.author = author } }
//书架: 书的集合 class Bookrack { var books: [Book] init(books: [Book]) { self.books = books } }
|
定义书架迭代器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| //书架迭代器 class BookrackIterator: Iterator { private let books: [Book] private var index = 0 init(books: [Book]) { self.books = books } func hasNext() -> Bool { return index < books.count ? true : false } func next() -> AnyObject { defer { index += 1 } return books[index] } }
|
实现具体聚集角色:
1 2 3 4 5 6 7
| extension Bookrack: Container { func makeIterator() -> Iterator { return BookrackIterator(books: self.books) } }
|
客户端调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| let book1 = Book(name: "C语言从入门到放弃", author: "C") let book2 = Book(name: "C++从入门到放弃", author: "C++") let book3 = Book(name: "Swift从入门到放弃", author: "Swift") let book4 = Book(name: "Python从入门到放弃", author: "Python")
let bookrack = Bookrack(books: [book1,book2,book3,book4])
let iterator = bookrack.makeIterator()
while(iterator.hasNext()) { let book = iterator.next() as! Book print("书名: " + book.name + "作者: " + book.author) }
|