2010-01-09 8 views
0

Imaginons que vous souhaitiez construire un Iterator qui crache des objets File. Quel type de données fournissez-vous habituellement au constructeur d'un tel itérateur?Construire un Iterator

  • un tableau d'objets de fichiers pré-construits, ou
  • simplement données brutes (tableau multidimensionnel, par exemple), et que les Iterator créer des objets de fichiers à la volée lorsque itérés?

Edit:
Bien que ma question était en fait d'être ment en général un possible, il semble que mon exemple est un peu à large pour aborder général, donc je vais élaborer un peu plus. Les objets File dont je parle sont en fait des références de fichiers provenant d'une base de données. Voir ces deux tableaux:

folder 
| id | folderId | name    | 
------------------------------------ 
| 1 |  null | downloads  | 

file 
| id | folderId | name    | 
------------------------------------ 
| 1 |  1 | instructions.pdf | 

Ils référencent les dossiers et fichiers réels sur un système de fichiers.

Maintenant, j'ai créé un objet FileManager. Cela sera en mesure de retourner une liste de dossiers et de fichiers. Par exemple:

FileManager::listFiles(Folder $folder); 

... retourneraient un itérateur d'objets de fichier (ou, venez y penser, plutôt des objets FileReference) de la base de données.

Alors ma question se résume à: Si l'objet FileManager construit le Iterator dans ListFiles() voulez-vous faire quelque chose comme ça (code de pseudo):

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); 

} 

ou (pseudo code):

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); 

} 

Espérons que cela clarifie un peu les choses.

Répondre

1

Quel est votre objet « Fichier » censé être? Un handle ouvert vers un fichier ou une représentation d'un chemin de système de fichiers pouvant être ouvert à son tour?

Il serait généralement une mauvaise idée d'ouvrir tous les fichiers à la fois - après tout, une partie du point d'utiliser un itérateur est que vous accédez à un seul objet à la fois. Votre itérateur peut générer un fichier ouvert à la fois, et laisser l'appelant prendre la responsabilité de le fermer, même si cela peut être légèrement étrange à utiliser. Vos besoins ne sont pas clairs, pour être honnête - dans mon expérience, la plupart des itérateurs qui produisent une série de fichiers utilisent quelque chose comme Directory.GetFiles(pattern) - vous ne leur transmettez pas les données brutes du tout, vous leur transmettez quelque chose qu'ils peut utiliser pour trouver les données pour vous.

Ce que vous essayez de comprendre n'est pas évident - vous avez l'impression d'essayer de poser une question générale, mais vous n'avez pas fourni assez d'informations pour nous permettre de vous conseiller.C'est comme demander: «Est-ce que je veux utiliser une chaîne ou un nombre entier? sans donner de contexte.

EDIT: Je vais probablement pousser tous les de cette logique dans FileIterator, personnellement. Sinon, il est difficile de voir quelle valeur cela apporte réellement. Dans une langue comme C# ou Python, vous n'avez pas besoin d'une classe séparée en premier lieu - vous utiliseriez simplement un générateur de description. En ce sens, cette question n'est pas la langue agnostique :(

+0

L'objet File est en fait un représentant d'un chemin de système de fichiers. Vous avez raison de dire que l'ouverture des fichiers physiques en une fois serait une mauvaise idée. Ce n'était en effet pas mon intention. J'ai mis à jour ma question. S'il vous plaît voir ma question étendue pour plus d'informations. Merci. –

1

Quelle est exactement votre iterator censé faire? Écrire des données dans des fichiers? Créez-les?

Un itérateur est un modèle pour itérant à travers les données, ce qui signifie fournissant données séquentielles d'une manière uniformous, non mutation eux.

+0

J'ai mis à jour ma question. S'il vous plaît voir ma question étendue pour plus d'informations. Merci. –

0

Cela dépend de ce dont vous avez besoin, par exemple, vous pourriez avoir:

  • une collection/liste des noms de fichiers à itérer,
  • le nom. d'un répertoire dans lequel vous voulez itérer,
  • votre itérateur pourrait décider lui-même quels fichiers il veut revenir,
  • ...

Vous pouvez concevoir une classe sous-jacente, par ex. FilenameCollection ou Directory qui a une méthode qui renvoie un itérateur approprié pour ce type d'objet (c'est-à-dire un itérateur "méthode usine"), au lieu d'exiger qu'un paramètre soit passé au constructeur de votre itérateur.

1

Je trouve que la question n'est pas claire. Parlons-nous d'itérateur ou d'usine?

Pour moi un Iterator fonctionne sur une collection pré-existante de choses et permet à l'appelant de travailler sur chaque chose à son tour. Quand vous dites "Spits Out", voulez-vous dire que le client peut travailler avec un fichier d'un ensemble de fichiers préexistant ou voulez-vous dire que vous itérez certaines données et avez l'intention de stocker ces données dans des fichiers que vous êtes generting. Si nous générons, alors nous avons une usine de fichiers. Je suppose que vous avez l'intention de traiter certains fichiers dans un système de fichiers. Je pense que votre Iterator s'apparente à un répertoire, il peut vous donner le prochain fichier qu'il connaît. Donc, je construis le "Driectory" en passant assez de données pour lui permettre de savoir quels fichiers vous voulez dire (pourrait être juste un chemin d'OS, pourrait être une sorte de "find" enxpression, une liste de références ftp, etc.) Je m'attends à ce qu'il me donne le prochain fichier pendant que je le répète.

---- mis à jour après la clarification de la question

Je pense que la question clé ici est lorsque les fichiers individuels doivent être ouverts. L'Iterator lui-même retournera raisonnablement un objet File correspondant à un handle de fichier ouvert, l'appelant peut alors simplement travailler avec le fichier. Mais iternellement, l'itérateur devrait travailler sur une liste de fichiers pré-ouverts ou sur une list de références de fichiers, les fichiers étant ouverts lorsque l'itérateur next() est utilisé.

Je pense que nous devrions faire le dernier, parce qu'il y a une surcharge dans avoir un fichier ouvert, par conséquent nous devrions ouvrir les fichiers seulement quand nous en avons besoin.

Cela nous amène à un autre point: qui ferme le fichier? Nous ne pouvons pas nous permettre de les garder tous ouverts. Peut-être que l'itérateur devrait fermer chaque fichier lorsque next() est appelé. Cela implique que l'itérateur lui-même a besoin d'une méthode close() pour permettre le nettoyage du fichier actuellement ouvert.Alternativement, nous devons explicitement documenter que la fermeture est la responsabilité du client.

+0

Hmmm, vous faites là un très bon point, en disant que le répertoire lui-même pourrait être l'Iterator. N'y avait pas pensé de cette façon. Merci! –

+0

Bien que vous fassiez des points valides, mon souci n'était pas d'ouvrir les fichiers physiques réels pour le moment. L'Iterator, dans un premier temps, sert uniquement à afficher les noms des fichiers dans une vue d'une application MVC. Plus tard, je veux que les objets File (Reference) me donnent le fichier physique réel à télécharger par exemple. Mais ce n'était pas encore mon problème. Ma préoccupation est plus de savoir comment générer l'Iterator. Mais puisque vous avez donné un autre point de vue sur l'Iterator, je pense que je vais repenser mon design. J'aime votre idée de "laisser le répertoire agir comme un itérateur". –