Language agnostic 构造迭代器
假设您想要构造一个迭代器来吐出文件对象。您通常向这种迭代器的构造函数提供什么类型的数据Language agnostic 构造迭代器,language-agnostic,oop,iterator,Language Agnostic,Oop,Iterator,假设您想要构造一个迭代器来吐出文件对象。您通常向这种迭代器的构造函数提供什么类型的数据 预先构造的文件对象数组,或 简单地使用原始数据(例如多维数组),并让迭代器在遍历时动态创建文件对象 编辑: 虽然我的问题实际上是尽可能的一般化,但我的例子似乎有点过于宽泛,无法解决一般性问题,所以我将进一步阐述。我所说的文件对象实际上是来自数据库的文件引用。请参见以下两个表: folder | id | folderId | name | ---------------------
- 预先构造的文件对象数组,或
- 简单地使用原始数据(例如多维数组),并让迭代器在遍历时动态创建文件对象
虽然我的问题实际上是尽可能的一般化,但我的例子似乎有点过于宽泛,无法解决一般性问题,所以我将进一步阐述。我所说的文件对象实际上是来自数据库的文件引用。请参见以下两个表:
folder
| id | folderId | name |
------------------------------------
| 1 | null | downloads |
file
| id | folderId | name |
------------------------------------
| 1 | 1 | instructions.pdf |
它们引用文件系统上的实际文件夹和文件
现在,我创建了一个FileManager对象。这将能够返回文件夹和文件的列表。例如:
FileManager::listFiles( Folder $folder );
。。。将从数据库返回文件对象的迭代器(或者,我认为是FileReference对象)
所以我的问题归结为:
如果FileManager对象在listFiles()中构造迭代器,您会这样做(伪代码):
或(伪代码):
希望这能澄清一些问题。你的迭代器到底应该做什么?将数据写入文件?创造它们
迭代器是对数据进行迭代的一种模式,这意味着以统一的方式提供顺序数据,而不是对它们进行变异。迭代器到底应该做什么?将数据写入文件?创造它们 迭代器是对数据进行迭代的一种模式,这意味着以统一的方式提供顺序数据,而不是对它们进行变异。您的“文件”对象是什么?文件的打开句柄,或者可以依次打开的文件系统路径的表示形式 一次打开所有文件通常不是一个好主意——毕竟,使用迭代器的部分原因是一次只能访问一个对象。您的迭代器可以一次生成一个打开的文件,并让调用方负责关闭它,尽管使用它可能有点奇怪 老实说,您的需求并不明确-根据我的经验,大多数生成一系列文件的迭代器都使用类似于
Directory.GetFiles(pattern)
的东西-您根本不向它们传递原始数据,而是向它们传递它们可以用来为您查找数据的东西
你想问什么并不明显——感觉你想问一个一般性的问题,但你没有提供足够的信息让我们给你建议。这就像问“我想使用字符串还是整数?”而不给出任何上下文
编辑:我个人可能会将所有这些逻辑推送到FileIterator
。否则很难看出它真正提供了什么价值。在C#或Python这样的语言中,您首先不需要单独的类——您只需要使用某种描述的生成器。从这个意义上说,这个问题不是语言不可知的:(您的“文件”对象是什么?文件的打开句柄,还是可以依次打开的文件系统路径的表示
一次打开所有文件通常不是一个好主意——毕竟,使用迭代器的一部分意义在于一次只能访问一个对象。迭代器一次可以生成一个打开的文件,并让调用方负责关闭它,尽管使用起来可能有点奇怪
老实说,您的需求并不明确-根据我的经验,大多数生成一系列文件的迭代器都使用类似于Directory.GetFiles(pattern)
的东西-您根本不向它们传递原始数据,而是向它们传递它们可以用来为您查找数据的东西
你想问什么并不明显——感觉你想问一个一般性的问题,但你没有提供足够的信息让我们给你建议。这就像问“我想使用字符串还是整数?”而没有给出任何上下文
编辑:我个人可能会将所有这些逻辑推到
FileIterator
中。否则,很难看出它真正提供了什么价值。在C#或Python这样的语言中,您首先不需要单独的类-您只需要使用某种描述的生成器。从这个意义上说,这个问题不是语言不可知的:(我发现这个问题不清楚
我们说的是迭代器还是工厂
对我来说,迭代器正在对预先存在的事物的集合进行操作,并允许调用方依次处理每个事物
当你说“Spits Out”时,你的意思是允许客户端使用一组预先存在的文件中的一个文件,还是说你正在迭代一些数据,并打算将这些数据存储在正在生成的文件中。如果我们正在生成,那么我们有一个文件工厂
我的猜测是,您打算在文件系统中处理一些文件。我认为您的迭代器类似于一个目录,它可以为您提供它知道的下一个文件。因此,我通过传递足够的数据来构造“Driectory”,让它知道您指的是哪些文件(可能只是一个操作系统路径,可能是某种“查找”)expression,一个类似ftp的引用列表,等等),并期望它在迭代时为我提供下一个文件
----更新了以下问题澄清
我认为这里的关键问题是应该在什么时候打开各个文件。迭代器本身将合理地返回一个与打开的文件句柄相对应的文件对象,然后调用者就可以处理该文件。但是,如果迭代器处理的是预打开的文件列表或文件引用列表,那么这些文件是g在使用迭代器next()时打开
我认为我们应该做后者,因为打开文件会有开销,因此我们应该只在需要时打开文件
这引出了另一点:谁关闭了
listFiles( Folder $folder )
{
// let's assume the following returns an multidimensional array of rows
$filesData = $db->fetch( $sqlForFetchingFilesFromFolder );
// let the Iterator take care of constructing the FileReference objects with each iteration
return FileIterator( $filesData );
}
listFiles( Folder $folder )
{
// let's assume the following returns an multidimensional array of rows
$filesData = $db->fetch( $sqlForFetchingFilesFromFolder );
$files = array();
for each( $filesData as $fileData )
{
$files.push ( new FileReference( $fileData ) );
}
// provide the Iterator with precomposed FileReference objects
return FileIterator( $files );
}