Apprenez le modèle de conception "Iterator" avec Python

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.

■ Itérateur (modèle d'itérateur)

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 W3sDesign_Iterator_Design_Pattern_UML.jpg UML class diagram iterator.png (Ce qui précède est cité sur Wikipedia)

□ Mémorandum

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.

■ Exemple de programme "Iterator"

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

■ Détails de l'exemple de programme

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

(1) Le rôle d'itérateur

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

(2) Le rôle de ConcreteIterator

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 classeBookShelf 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

(3) Le rôle de l'agrégat

ʻ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

(4) Le rôle de l'agrégat de béton

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

(5) Le rôle du client

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

(6) Autre

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

□ Mémorandum (Essayez d'utiliser Python Iterator!)

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.

■ URL de référence

Recommended Posts

Apprenez le modèle de conception "Iterator" avec Python
Apprenez le modèle de conception "Prototype" avec Python
Apprenez le modèle de conception "Builder" avec Python
Apprenez le modèle de conception "Observer" en Python
Apprenez le modèle de conception "Proxy" en Python
Apprenez le modèle de conception "Commande" en Python
Apprenez le modèle de conception "Visiteur" avec Python
Apprenez le modèle de conception "Bridge" avec Python
Apprenez le modèle de conception "Mediator" avec Python
Apprenez le modèle de conception "Décorateur" avec Python
Apprenez le modèle de conception «Stratégie» avec Python
Apprenez le modèle de conception "Composite" avec Python
Apprenez le modèle de conception "État" en Python
Apprenez le modèle de conception "Adapter" avec Python
Apprenez le modèle de conception "Abstract Factory" avec Python
Apprenez le modèle de conception "Méthode de modèle" en Python
Apprenez le modèle de conception "Méthode d'usine" en Python
Apprenez le modèle de conception «Chaîne de responsabilité» en Python
Apprenez le modèle de conception "Singleton" avec Python
Apprenez le modèle de conception "Façade" avec Python
Implémenter le modèle Singleton en Python
Motif singleton en Python
Modèle d'itérateur en Java
J'ai écrit un modèle de conception en kotlin, édité par Iterator
Modèles de conception en Python: introduction
Python Design Pattern - Méthode de modèle
Obtenir l'API arXiv en Python
Python dans le navigateur: la recommandation de Brython
Enregistrez le fichier binaire en Python
Obtenez le chemin du bureau en Python
Obtenez le chemin du script en Python
Dans la commande python, python pointe vers python3.8
Diviser l'itérateur en morceaux avec python
Accédez à l'API Web en Python
J'ai écrit la file d'attente en Python
Calculer le mois précédent en Python
Examiner la classe d'un objet avec python
Obtenez le chemin du bureau en Python
Obtenez le nom d'hôte en Python
Accéder à l'API Twitter avec Python
La première étape de Python Matplotlib
J'ai écrit la pile en Python
Maîtriser le module lowref en Python
Apprenez les bases de Python ① Débutants élémentaires
Charger le SDK Python distant avec IntelliJ
Essayez d'utiliser l'API Wunderlist en Python
Vérifiez le comportement du destroyer en Python
[Python Kivy] À propos de la modification du thème de conception
Essayez d'utiliser l'API Kraken avec Python
Ecrire le test dans la docstring python
[Gang of Four] Apprentissage des modèles de conception - Itérateur
Prenez la somme logique de List en Python (fonction zip)
Modèle de conception du GoF à partir du problème 2. Structure
Afficher Python 3 dans le navigateur avec MAMP
Tweet à l'aide de l'API Twitter en Python
Vérifiez si l'URL existe en Python
Exécuter l'interpréteur Python dans le script
Le résultat de l'installation de python sur Anaconda