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.
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)
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.
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 **. ** **
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
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.
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.
Recommended Posts