À propos du modèle de visiteur

introduction

J'ai eu l'occasion de mettre en œuvre le modèle Visiteur dans mon travail et je ne l'ai pas bien compris, c'est donc un résumé de ce que j'ai appris des livres suivants.

Aperçu

Le modèle Visiteur peut séparer la structure des données et le traitement.

Le modèle Visiteur est divisé en une classe qui contient des données et une classe qui implémente l'algorithme (classe Visiteur).

Si vous avez une structure de données dans votre application et que certains algorithmes accèdent à cette structure de données

Le modèle Visiteur permet à la structure de données de se concentrer sur la conservation et l'accès aux données.

Vous pouvez étendre la fonctionnalité sans modifier la classe existante. (Principe d'ouverture / fermeture)

Contexte

De nombreux éléments sont stockés dans la structure de données et je souhaite effectuer un traitement pour chaque élément.

Où dois-je écrire le code de «traitement» à ce moment? Si vous écrivez dans une classe qui représente la structure de données ** La classe de structure de données doit être modifiée chaque fois qu'un nouveau traitement est requis. ** **

Le modèle Visiteur s'est avéré utile pour résoudre les problèmes ci-dessus.

Fonctionnalité

Selon Introduction to Design Patterns Learned in Java Language, les relations suivantes sont associées entre les classes de structure de données et les algorithmes qui décrivent les algorithmes. il y a.

Soit la classe qui contient la structure de données la classe «Visitable» et la classe qui décrit l'algorithme de la structure de données la classe «Visiteur».

Définissez la méthode visit (visitable) dans la classe Visitor. Dans visit (), écrivez l'algorithme en accédant aux attributs et au comportement de la classe de la structure de données.

D'autre part, la classe Visitable définit la méthode ʻaccept (visiteur). Dans ʻaccept (visiteur) , appelezvisit ()de l'objet Visiteur passé dans l'argument **. ** **

Exemple de code

Décrit une classe de structure de données (classe Visitable). Décrit une classe qui contient des données de type liste et une classe qui contient des données de type dictionnaire. Définissez une méthode (ʻaccept () `) qui accepte la classe Visitor dans chaque classe.

visitable.py


class VisitableList(list):

    def accept(self, visitor):
        visitor.visit_list(self)

class VisitableDict(dict):

    def accept(self, visitor):
        visitor.visit_dict(self)

Ensuite, écrivez la classe Visitor qui décrit l'algorithme. Dans le code ci-dessous, les données détenues par la classe de la structure de données décrite ci-dessus sont simplement sorties en standard.

visitor.py


class Printer(object):
    def visit_list(self, instance):
        print('Le contenu de la liste: {}'.format(instance))

    def visit_dict(self, instance):
        print('Clés dans le dictionnaire: {}'.format(
            ', '.join(instance.keys())
        ))

Utilisez ensuite la classe de structure de données et la classe Visiteur comme indiqué dans l'exemple de code ci-dessous. Créer un objet de classe de structure de données, Objet de structure de données .accept (objet Visiteur) Il est décrit comme.

main.py



def main():

    vistitable_list = VisitableList([1, 2, 3, 5])
    vistitable_list.accept(Printer())
    vistitable_dict = VisitableDict({'one': 1, 'two': 2, 'three': 3})
    vistitable_dict.accept(Printer())

if __name__ == "__main__":

    main()
$ python main.py
Le contenu de la liste: [1, 2, 3, 5]
Clés dans le dictionnaire: one, two, three

Connectez les classes de visiteurs et de visiteurs en utilisant les caractéristiques de l'introspection

L'introspection est la nature et la couverture d'un objet (dans ce cas, un objet). Une fonctionnalité qui peut être étudiée pour couvrir ce qui est possible.

Par exemple, référencer ou récupérer "ce que les propriétés ont" pour un objet est appelé introspection.

Le code suivant tire parti des caractéristiques de l'introspection et décrit une classe qui connecte la classe Visitor à la classe Visitor.

class Connect():
    def __init__(self, visited, vistor):
        self.__cls = visited.__class__.__name__
        self.__method_name = 'visit_%s' % self.__cls
        self.__method = getattr(vistor, self.__method_name, None)
        
        # visit()Mis en œuvre
        self.__method(visited)

vistied .__ class .___ name__ etgetattr ()sont des introspections.

Dans le code ci-dessous, implémentez-le à l'aide de la classe Printer décrite précédemment.

main.py


if __name__ == "__main__":

    Connect([1, 2, 3], Printer())
$ python main.py
Le contenu de la liste: [1, 2, 3]
Clés dans le dictionnaire: one, two, three

L'introspection élimine le besoin d'implémenter accept () dans la classe Visitor.

Impressions

Dans Introduction to Design Patterns Learned in Java Language, en tant que forme de base, Définissez ʻaccept () dans la classe de structure de données et la méthode visit () `dans la classe qui implémente l'algorithme. Ensuite, dans la méthode définie, nous appelons les méthodes de l'autre. (Une technique appelée double expédition)

Dans Expert Python Programming Revised 2nd Edition, en Python, les attributs des objets sont dynamiquement En conséquence, il a été constaté que le modèle Visiteur pouvait être implémenté sans utiliser la méthode accept ().

Dans tous les cas, je pense qu'il est nécessaire d'implémenter la méthode visit () dans la classe de définition (Visiteur) après avoir pleinement compris les attributs et le comportement de la classe dans la structure de données.

Les références

Recommended Posts

À propos du modèle de visiteur
À propos du test
À propos de la file d'attente
Apprenez le modèle de conception "Visiteur" avec Python
Modèle de visiteur en Python
À propos de la fonction Déplier
À propos de la commande de service
À propos de la matrice de confusion
À propos du module Python venv
À propos de la fonction enumerate (python)
À propos du problème du voyageur de commerce
À propos de la compréhension du lecteur en 3 points [...]
À propos des composants de Luigi
À propos des fonctionnalités de Python
Pensez au problème de changement minimum
Changez le modèle Flyweight en Pythonic (?) (2)
À propos du problème du vendeur de patrouille commandé
À propos de la valeur de retour de pthread_mutex_init ()
Implémenter le modèle Singleton en Python
À propos de la valeur de retour de l'histogramme.
À propos du type de base de Go
À propos de la limite supérieure de threads-max
Changez le modèle Flyweight en Pythonic (?) (1)
À propos de l'option moyenne de sklearn.metrics.f1_score
À propos du comportement de yield_per de SqlAlchemy
À propos de la taille des points dans matplotlib
À propos de la liste de base des bases de Python
Pensez grossièrement à la fonction de perte
À propos du fait que l'objet recompilé peut être utilisé pour le modèle re.match
J'ai étudié les modèles de conception (mémo personnel) Partie 5 (modèle composite, modèle décorateur, modèle visiteur)
Apprenez le modèle de conception "Builder" avec Python
[Python Kivy] À propos de la modification du thème de conception
[Gang of Four] Apprentissage des modèles de conception - Visiteur
Apprenez le modèle de conception "Flyweight" en Python
Apprenez le modèle de conception "Observer" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Proxy" en Python
Notes diverses sur le framework Django REST
Modèle de conception du GoF à partir du problème 2. Structure
[OpenCV] À propos du tableau retourné par imread
À propos de NumFOCUS, une organisation de support open source
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
Pensez grossièrement à la méthode de descente de gradient
[Python] Résumez les éléments rudimentaires du multithreading
À propos de l'environnement de développement que vous utilisez
Apprenez le modèle de conception "Iterator" avec Python
À propos de la relation entre Git et GitHub
À propos de l'équation normale de la régression linéaire
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 "Singleton" 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 "Façade" avec Python
Modèle de conception GoF à partir du problème 3. Comportement
Un mémo que j'ai essayé le tutoriel Pyramid