迭代器
迭代器
迭代器是一种行为设计模式,让你能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。
案例:通讯录
// 集合接口必须声明一个用于生成迭代器的工厂方法。如果程序中有不同类型的迭
// 代器,你也可以声明多个方法。
interface SocialNetwork is
method createFriendsIterator(profileId):ProfileIterator
method createCoworkersIterator(profileId):ProfileIterator
// 每个具体集合都与其返回的一组具体迭代器相耦合。但客户并不是这样的,因为
// 这些方法的签名将会返回迭代器接口。
class WeChat implements SocialNetwork is
// ...大量的集合代码应该放在这里...
// 迭代器创建代码。
method createFriendsIterator(profileId) is
return new WeChatIterator(this, profileId, "friends")
method createCoworkersIterator(profileId) is
return new WeChatIterator(this, profileId, "coworkers")
// 所有迭代器的通用接口。
interface ProfileIterator is
method getNext():Profile
method hasMore():bool
// 具体迭代器类。
class WeChatIterator implements ProfileIterator is
// 迭代器需要一个指向其遍历集合的引用。
private field weChat: WeChat
private field profileId, type: string
// 迭代器对象会独立于其他迭代器来对集合进行遍历。因此它必须保存迭代器
// 的状态。
private field currentPosition
private field cache: array of Profile
constructor WeChatIterator(weChat, profileId, type) is
this.weChat = weChat
this.profileId = profileId
this.type = type
private method lazyInit() is
if (cache == null)
cache = weChat.socialGraphRequest(profileId, type)
// 每个具体迭代器类都会自行实现通用迭代器接口。
method getNext() is
if (hasMore())
currentPosition++
return cache[currentPosition]
method hasMore() is
lazyInit()
return cache.length < currentPosition
// 这里还有一个有用的绝招:你可将迭代器传递给客户端类,无需让其拥有访问整
// 个集合的权限。这样一来,你就无需将集合暴露给客户端了。
//
// 还有另一个好处:你可在运行时将不同的迭代器传递给客户端,从而改变客户端
// 与集合互动的方式。这一方法可行的原因是客户端代码并没有和具体迭代器类相
// 耦合。
class SocialSpammer is
method send(iterator: ProfileIterator, message: string) is
while (iterator.hasNext())
profile = iterator.getNext()
System.sendEmail(profile.getEmail(), message)
// 应用程序(Application)类可对集合和迭代器进行配置,然后将其传递给客户
// 端代码。
class Application is
field network: SocialNetwork
field spammer: SocialSpammer
method config() is
if working with WeChat
this.network = new WeChat()
if working with LinkedIn
this.network = new LinkedIn()
this.spammer = new SocialSpammer()
method sendSpamToFriends(profile) is
iterator = network.createFriendsIterator(profile.getId())
spammer.send(iterator, "非常重要的消息")
method sendSpamToCoworkers(profile) is
iterator = network.createCoworkersIterator(profile.getId())
spammer.send(iterator, "非常重要的消息")