En tant que matériel d'apprentissage des modèles de conception du GoF, le livre «Introduction aux modèles de conception appris dans le langage Java augmenté et révisé» semble être utile. Cependant, comme les exemples repris sont basés sur JAVA, j'ai essayé la même pratique avec Python pour approfondir ma compréhension.
Le modèle Iterator est l'un des modèles de conception définis par le GoF (Gang of Four; 4 gangs). En rendant indépendant les moyens d'énumération des éléments de l'objet conteneur, le but est de fournir des itérateurs qui ne dépendent pas des spécifications internes du conteneur.
UML class and sequence diagram UML class diagram (Ce qui précède est cité sur Wikipedia)
Il semble que le modèle Iterator est destiné au traitement lorsque beaucoup de choses sont rassemblées, en les pointant dans l'ordre et en balayant le tout. ʻIterator` est parfois appelé ** iterator ** en japonais. Vous les voyez souvent lorsque vous êtes impliqué dans la programmation Python.
Je voudrais exécuter un exemple de programme qui utilise le modèle Iterator et vérifier le comportement suivant.
--Ajoutez des livres «Le monde en 80 jours» à la bibliothèque
--Ajoutez des livres bibliques à la bibliothèque
--Ajoutez des livres Cendrillon
à la bibliothèque
--Ajoutez les livres Daddy-Long-Legs
à la bibliothèque
--Afficher les titres des livres actuellement sur l'étagère
$ python Main.py
Aroun d the World in 80 days
Bible
Cinderella
Daddy-Long-Legs
Un code similaire a été téléchargé dans le référentiel Git. https://github.com/ttsubo/study_of_design_pattern/tree/master/Iterator/step1
.
├── Main.py
└── iterator
├── __init__.py
├── aggregate.py
├── book.py
└── iterator.py
C'est le rôle qui définit l'interface qui scanne les éléments dans l'ordre. Dans l'exemple de programme, la classe ʻIterator` remplit ce rôle.
iterator/iterator.py
from abc import ABCMeta, abstractmethod
class Iterator(metaclass=ABCMeta):
@abstractmethod
def hasNext(self):
pass
@abstractmethod
def next(self):
pass
C'est le rôle qui implémente en fait l'interface définie par le rôle de ʻIterator. Dans l'exemple de programme, la classe
BookShelfIteratorremplit ce rôle. Ce rôle doit disposer des informations nécessaires à l'analyse. Dans l'exemple de programme, l'instance de la classe
BookShelf est mémorisée par la variable d'instance
self .__ bookShelf, et le livre d'intérêt est mémorisé par la variable d'instance
self .__ index`.
iterator/book.py
from iterator.iterator import Iterator
...(snip)
class BookShelfIterator(Iterator):
def __init__(self, bookShelf):
self.__bookShelf = bookShelf
self.__index = 0
def hasNext(self):
return True if self.__index < self.__bookShelf.getLength() else False
def next(self):
book = self.__bookShelf.getBookAt(self.__index)
self.__index += 1
return book
ʻIterator C'est le rôle qui définit l'interface qui crée le rôle. L'interface est une méthode d'abstraction qui crée "une personne qui scanne les éléments que j'ai dans l'ordre". Dans l'exemple de programme, la classe ʻAggregate
remplit ce rôle.
iterator/aggregate.py
from abc import ABCMeta, abstractmethod
class Aggregate(metaclass=ABCMeta):
@abstractmethod
def iterator(self):
pass
ʻAggregate C'est le rôle qui implémente en fait l'interface définie par le rôle. Créez un rôle concret ʻIterator
, c'est-à-dire une instance du rôle ConcreteIterator
.
Dans l'exemple de programme, la classe BookShelf
remplit ce rôle.
iterator/book.py
from iterator.aggregate import Aggregate
...(snip)
class BookShelf(Aggregate):
def __init__(self, maxSize):
self.__last = 0
self.__books = [None] * maxSize
def getBookAt(self, index):
return self.__books[index]
def append(self, book):
self.__books[self.__last] = book
self.__last += 1
def getLength(self):
return self.__last
def iterator(self):
return BookShelfIterator(self)
Dans l'exemple de programme, la méthode startMain
remplit ce rôle.
Main.py
from iterator.book import Book, BookShelf
def startMain():
bookShelf = BookShelf(4)
bookShelf.append(Book(name="Aroun d the World in 80 days"))
bookShelf.append(Book(name="Bible"))
bookShelf.append(Book(name="Cinderella"))
bookShelf.append(Book(name="Daddy-Long-Legs"))
it = bookShelf.iterator()
while it.hasNext():
book = it.next()
print(book.getName())
if __name__ == '__main__':
startMain()
Gérez les titres de livres.
iterator/book.py
class Book(object):
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
En programmation Python, je vois souvent des itérateurs. Pour plus d'informations sur les itérateurs Python, reportez-vous à cet article Web "[Introduction à Python] Qu'est-ce que les itérateurs?". .. De plus, lors de la définition d'une nouvelle classe, il semble que les conditions suivantes doivent être remplies pour avoir les propriétés d'un itérateur.
--Dispose d'une méthode __iter__
qui se renvoie elle-même
--Dispose d'une méthode __next__
qui renvoie les valeurs des colonnes d'élément que vous gérez une par une.
--Dans la méthode __next__
, une exceptionStopIteration
est déclenchée lorsque les éléments sont épuisés.
Je voudrais réécrire l'exemple de programme avec ** Python Iterator **. Un code similaire a été téléchargé dans le référentiel Git. https://github.com/ttsubo/study_of_design_pattern/tree/master/Iterator/step2
iterator/book.py
class Book(object):
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
class BookShelf(object):
def __init__(self):
self.__books = []
def append(self, book):
self.__books.append(book)
def __iter__(self):
self.__index = 0
return self
def __next__(self):
if self.__index >= len(self.__books):
raise StopIteration()
book = self.__books[self.__index]
self.__index += 1
return book
Main.py
from iterator.book import Book, BookShelf
def startMain():
bookShelf = BookShelf()
bookShelf.append(Book(name="Aroun d the World in 80 days"))
bookShelf.append(Book(name="Bible"))
bookShelf.append(Book(name="Cinderella"))
bookShelf.append(Book(name="Daddy-Long-Legs"))
for book in bookShelf:
print(book.getName())
if __name__ == '__main__':
startMain()
C'est beaucoup plus simple. Déplaçons-le.
$ python Main.py
Aroun d the World in 80 days
Bible
Cinderella
Daddy-Long-Legs
Puisqu'il est identique au résultat de la première opération, il est terminé pour le moment.
Recommended Posts