`

5-Iterators: decoupling algorithms from containers

阅读更多

In the process, he realized that iterators are central to the use of algorithms, because they decouple the algorithms from the specific type of containe...只看这个,不是很好理解。

找了两个资料,感觉是比较好的例子:

<1>

Iterator模式的疑问

http://www.jdon.com/jivejdon/thread/34664

 

JAVA COLLECTION类都提供Iterator模式来迭代的取数据,比如ArrayList最终实现Iterable接口,但是
(一)
for(int i=0,i<size;i++){
a.get(i);
......
}

(二)
Iterator i = a.inerator();
while(i.hasNext()){
......
}

1和2都能遍历list实例a的所有元素,没看出用iterator有什么优势。

起先我的想法就是Iterator提供了List的一个不可变视图,如果你想把List发布给一个方法查看而又不希望这个方法能修改它,则发给给该方法一个List的不可更改视图,但是这个想法有几个问题:
(1)Iterator并非不可改,有remove方法
(2)如果是发布不可变试图的话完全可以用Collections.unmodifyList(a);
(3)如果仅仅是发布不可变视图的话也未必要是Iterator这个形式,试想一下,一个方法的参数是Iterator将是多么晦涩难理解的,我也没见过这个用的。

我的第二个想法是Iterable接口是所有Collection对象都必实现的,也许在List里体现不出优势,在其他集合类里能体现出来,List实现Iterable只是List作为集合类所顺理成章实现的。

到底Iterator的优势在哪里

 

其中一个评论比较有总结性,这应该就是面向接口编程+遵守规范的优越性!

 

为什么使用iterator,就是因为用***.iterator 来隐藏***的内部实现。

 

<2>

Iterator模式的几种用法:

http://www.jdon.com/jivejdon/thread/32038

Iterator模式的几种用法

在网络上看帖子时发现不少模式的初学者对Iterator模式的理解仅仅停留在从类库的容器类取得Iterator来遍历容器中的内容的程度。

因此在这里写几个例子,来加深大家对Iterator模式的理解。

 

对容器中元素的访问涉及到3个方面。

1.容器的类型

2.检索容器内元素的方法

3.对元素的操作

比如说我们有一个表示书店的book_store类。里面保存了各种各样的book类的实例。

book类有name和type两种属性。表示书的名字和类别。

因此book_store类内部会用一个容器来保存book的实例。比如list。

class book

{

public:

string name;

string type;

};

 

class book_store

{

private:

list<book> m_books;

};

 

我们现在有这样一个简单的应用,那就是输出所有的书名到屏幕。

那么我们来看一下在引入Iterator模式前有那几种实现方法,各有什么缺点。

1.给book_store类增加一个print_book_name的函数。来实现这个功能。

这样做的缺点有两个:

(1).将输入输出逻辑和业务对象绑定在一起,导致了今后系统难以变更。

(2).输出逻辑和内部实现绑定。

比如现在要把输出到屏幕改成输出到log文件的话,那么就需要修改print_book_name了。

2.给book_store类增加一个get_list函数。然后写一个print_book类来负责打印书名的列表。这是一个初学者常用的方式。表面上看来似乎两个类各担其责,一个表示业务对象一个负责打印。

如果需要打印到log文件的话,只要新增加一个log_book类,book_store和print_book都不受影响。解决了上面的这个问题。

这样做的缺点是:

(1).把book_store类的内部实现给暴露出来了,违反了封装的原则。

如果现在把内部容器类型从list换成了vector的话,就要修改输出逻辑了。也就是说,要同时改写print_book类和log_book类。

3.增加一个list和vector类共同的基类/接口,比如I_container。然后给book_store类增加一个get_books函数,返回I_container。

这在一定程度上解决了上面的问题。但是并不彻底。应为还是暴露了内部的实现,只不过从list上升到了I_container。

· 如果现在系统发生了变化,book_store不再在本地保存books了,而是需要通过网络取得的话,print_book和log_book就无法对应了。

· 另一个限制是,我需要一个新的机能,那就是打印所有type为”烹饪书”的机能的话,就需要一个print_cook_book类了,而这里边的格式化代码和输出代码和print_book是相同的。重复代码是维护的噩梦。

 

接下来我们看一下Iterator模式如何解决以上的这些问题。

首先,我们引入一个I_iterator的Interface。

然后创建一个I_iterator的实现类all_book_iterator。这个类可以迭代book_store中的所有book。

接下来创建一个print_book类,从I_iterator中取得每一个book,然后打印到屏幕。

 

下面我们看一下如何对应上面的这些需求变更。

1.要求输出到log文件

追加一个log_book类,其他都类都不需要改变。

2.将内部容器从list变成vector。

修改iterator中的相关代码。Iterator的使用者不会受到影响。

3.从网络取得数据。

修改iterator中的相关代码。Iterator的使用者不会受到影响。

4.按照type检索

在iterator中添加一个type的属性,或者是构造一个新的type_search_iterator。

在iterator中把不符合检索条件的book过滤掉。

5.按照某一特定顺序输出book名到屏幕,或是log文件。

实现一个按该顺序输出的iterator。

6.以同样的方式打印cd_store。

实现对应于cd_store的iterator。

 

可见,iterator模式在各种iterator中封装了检索元素的方法。

将容器和对容器中元素的操作完全隔开。

大大增加了代码的可重用性。

分享到:
评论

相关推荐

    deeplearning4j-datavec-iterators-1.0.0-M1.1-API文档-中文版.zip

    赠送jar包:deeplearning4j-datavec-iterators-1.0.0-M1.1.jar; 赠送原API文档:deeplearning4j-datavec-iterators-1.0.0-M1.1-javadoc.jar; 赠送源代码:deeplearning4j-datavec-iterators-1.0.0-M1.1-sources....

    deeplearning4j-utility-iterators-1.0.0-M1.1-API文档-中文版.zip

    赠送jar包:deeplearning4j-utility-iterators-1.0.0-M1.1.jar; 赠送原API文档:deeplearning4j-utility-iterators-1.0.0-M1.1-javadoc.jar; 赠送源代码:deeplearning4j-utility-iterators-1.0.0-M1.1-sources....

    deeplearning4j-datavec-iterators-1.0.0-M1.1-API文档-中英对照版.zip

    赠送jar包:deeplearning4j-datavec-iterators-1.0.0-M1.1.jar; 赠送原API文档:deeplearning4j-datavec-iterators-1.0.0-M1.1-javadoc.jar; 赠送源代码:deeplearning4j-datavec-iterators-1.0.0-M1.1-sources....

    deeplearning4j-utility-iterators-1.0.0-M1.1-API文档-中英对照版.zip

    赠送jar包:deeplearning4j-utility-iterators-1.0.0-M1.1.jar; 赠送原API文档:deeplearning4j-utility-iterators-1.0.0-M1.1-javadoc.jar; 赠送源代码:deeplearning4j-utility-iterators-1.0.0-M1.1-sources....

    rust-iterators:Rust迭代器的基本用法

    如何编译和运行示例代码: git clone https://github.com/rustomax/rust-iterators.gitcd rust-iterators/cargo run内容介绍生活是重复性的,生活中的大多数事物都是一系列物品。 以编程方式,我们经常需要对这些...

    underscore-arity-iterators:扩展下划线以添加 Underscore 提供的许多集合迭代器的 arity-bound 等价物,例如

    npm install underscore-arity-iterators 或者,下载单个underscore.arity-iterators.js文件。 该文件,当包含在页面上或 Node require d 时,会将自身混合到 Underscore 中,它希望以require('underscore')或全局...

    arvores-iterators:Estudo

    5. **比较和排序**:如果使用了`TreeSet`或`NavigableMap`,会涉及到比较器(Comparator)的概念,学习如何根据特定规则对树中的元素进行排序。 6. **测试和调试**:编写单元测试来验证树和迭代器的功能,确保它们...

    js-iterators:JS中的Ruby样式迭代器

    js-iterators(零依赖) JS中的Ruby样式迭代器。 JS中的Ruby样式范围[ ... 1. . _10 ] ; // [1, 2, 3, 4, 5, 6, 7, 8, 9][ ... 1. . _ - 10 ] ; // [1, 0, -1, -2, ..., -9][ ... Math . PI . _9 ] ; // [3....

    Backtracking-iterators:回溯迭代器

    在Backtracking-iterators-master这个项目中,可能包含了不同类型的回溯迭代器的实现示例,包括上述的各种遍历方法。通过阅读和分析这些代码,你可以深入理解如何在Java中有效地应用回溯迭代器来处理树形结构的问题...

    presto-accumulo:Presto Accumulo集成

    presto-accumulo-iterators-要在TabletServer上安装的Accumulo迭代器的集合。 这些迭代器是用户使用连接器所必需的。 presto-accumulo-tools-一个Java项目,其中包含一些工具来帮助完成元数据管理任务,而使用SQL...

    deeplearning4j-datavec-iterators-1.0.0-M1.1.jar中文-英文对照文档.zip

    注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...

    spl-iterators-course:即将举行的SPL迭代器课程的代码

    这个“spl-iterators-course”可能是针对那些希望深入理解JavaScript迭代器机制的开发者设计的。 在JavaScript中,迭代器是ES6引入的一项关键特性,它为遍历各种数据结构提供了统一的方法。通过实现`Symbol....

    talk-very-iterators-so-lazy:我的演讲的幻灯片和笔记“非常迭代。太懒了!太神奇了!”

    非常迭代器。 太懒了。 惊奇! 作者:Maxim Vuets-狂热者和理性主义者 片长:20分钟 迭代器是一个精巧的概念,用于在简单的界面后面隐藏访问数据集合的复杂性。 此外,它使人们可以从惰性评估,模块化代码设计和...

    asp.net经典面试题

    - Iterators(迭代器):用于自定义迭代逻辑,如yield return关键字。 - Partial Classes(部分类):允许将类的定义分散到多个源文件中。 - Properties(属性)的改进:支持自动实现的属性。 7. **String与...

    tree-3.1: tree.hh: an STL-like C++ tree class

    Various types of iterators are provided (post-order, pre-order, and others). Where possible the access methods are compatible with the STL or alternative algorithms are available. The library is ...

    haXe2语言参考手册(英文)

    #### 迭代子 (Iterators) - **实现迭代子** (`Implementing Iterator`): - 如何定义一个迭代子。 - **可迭代对象** (`Iterable Objects`): - 定义对象如何被遍历。 #### 属性 (Properties) - **示例** (`Sample...

    12-iterators-and-generators(迭代器和生成器12).pdf

    let list = [4, 5, 6]; for (let i in list) { console.log(i); // 输出:"0", "1", "2" } for (let i of list) { console.log(i); // 输出:"4", "5", "6" } ``` **Map和Set的迭代** Map和Set是JavaScript中的...

    deeplearning4j-utility-iterators-1.0.0-M1.1.jar中文-英文对照文档.zip

    注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...

    C++标准库源代码

    1. 容器(Containers): - `std::vector`:动态数组,支持随机访问和高效插入删除。 - `std::deque`:双端队列,支持两端的快速插入和删除。 - `std::list`:双向链表,元素可以快速在任何位置插入和删除。 - `...

    cffect stl eg(原版)pdf

    **标题:** 优先使用范围成员函数而非单个元素的对应版本 (Item 5) - **核心思想:** - 使用范围成员函数(如`std::sort(begin(), end())`)通常比使用其单元素版本更高效。 - 范围成员函数可以利用额外的信息来...

Global site tag (gtag.js) - Google Analytics