[PYTHON] Modèle de conception #Proxy

J'ai pratiqué les modèles de conception afin de pouvoir écrire du code conscient du design. D'autres modèles de conception seront publiés fréquemment.

Préface

L'objectif principal est de comprendre quand, quoi et comment utiliser les modèles de conception. (Je suis nouveau en Java ou dans un langage à typage statique, et je n'ai pas une longue histoire de python, donc je pense qu'il y a des choses qui ne ressemblent pas à Pythonista. Si vous avez des suggestions, apprenez-moi s'il vous plaît.)

Cette fois, le motif Proxy était lié à la structure.

Qu'est-ce que le proxy

Préparez un proxy pour contrôler la création d'instances et les restrictions d'accès, et demandez au proxy de faire le travail jusqu'à ce qu'il soit nécessaire. Cependant, lorsque l'agent dépasse la plage qui peut être effectuée, l'agent donne le rôle à la personne d'origine.

Aperçu

Cet exemple de programme est une «imprimante nommée». La classe Main crée une instance de classe (agent) pour PrinterProxy. Nommez l'instance «Alice» et affichez le nom. Puis renommez-le en "Bob" et affichez ce nom.

En définissant ou en obtenant le nom, nous n'avons pas encore créé d'instance (personne) de la classe d'imprimante réelle. La classe PrinterProxy prend en charge la partie de la configuration et de l'obtention du nom. Enfin, la classe PrinterProxy crée une instance de la classe Printer uniquement lorsqu'il est temps d'appeler la méthode my_print et d'imprimer réellement.

Une interface appelée Printable est définie pour assimiler la classe PrinterProxy à la classe Printer. Ici, l'exemple de programme est créé en supposant qu'il faut beaucoup de temps pour instancier la classe Printer. Afin d'exprimer que cela prend du temps, j'appelle une méthode appelée heavy_job du constructeur et gagne quelques secondes en tant que "traitement lourd".

Diagramme de classe global

クラス図

Diagramme de séquençage

シーケンス図

printer.py


import sys
import time
from printable import Printable


class Printer(Printable):

    def __init__(self, name):
        self.__name = name
        self.__heavy_job('Instance d'imprimante({0})Est en cours de génération'.format(self.__name))

    def set_printer_name(self, name):
        self.__name = name

    def get_printer_name(self):
        return self.__name

    def my_print(self, string):
        print('===' + ' ' + self.__name + ' ' + '===')
        print(string)

    def __heavy_job(self, msg):
        sys.stdout.write(msg)
        for i in range(1, 5):
            try:
                time.sleep(1)
            except InterruptedError:
                pass
            sys.stdout.write('.')
        print('Terminé.')

La classe Printer est une classe qui représente «la personne». Je fais du heavy_job comme un "gros travail". Après cela, il y a set_printer_name pour définir le nom, get_printer_name pour obtenir le nom et my_print pour afficher la chaîne de caractères. Le centre du modèle Proxy est vers la classe PrinterProxy.

printable.py


from abc import abstractmethod


class Printable():

    @abstractmethod
    def set_printer_name(self, name):
        pass

    @abstractmethod
    def get_printer_name(self):
        pass

    @abstractmethod
    def my_printer(self, string):
        pass

L'interface imprimable sert à assimiler la classe PrinterProxy à la classe Printer.

printer_proxy.py


from printable import Printable
from printer import Printer


class PrinterProxy(Printable):

    def __init__(self, name):
        self.__name = name
        self.__real = None

    def set_printer_name(self, name):
        if (self.__real is not None):
            self.__real.set_printer_name(name)
        self.__name = name

    def get_printer_name(self):
        return self.__name

    def my_print(self, string):
        self.__realize()
        self.__real.my_print(string)

    def __realize(self):
        if (self.__real is None):
            self.__real = Printer(self.__name)

La classe PrinterProxy agit comme un agent. Implémente l'interface imprimable. Le champ du nom sert à contenir le nom et le champ réel sert à contenir la «personne».

Dans le constructeur, définissez le nom. La méthode set_printer_name définit un nouveau nom. Si real n'est pas None, définissez également le nom de la personne. Toutefois, si real est None, il renvoie une valeur dans le champ de nom PrinterProxy.

Puisque la méthode my_print est un processus en dehors de la portée de cet agent, appelez la méthode de réalisation pour générer la "personne". Après avoir exécuté la méthode de réalisation, le champ réel contient la personne, appelez donc real.print. C'est la "délégation".

** Peu importe le nombre de fois que vous appelez set_printer_name ou get_printer_name, l'imprimante ne sera pas instanciée. Aucune instance d'imprimante n'est créée. ** Une instance d'imprimante est créée uniquement lorsque la "personne" est nécessaire. (Les utilisateurs de PrinterProxy ne savent pas du tout si la personne a été générée et il n'y a pas lieu de s'en inquiéter.)

La méthode de réalisation crée une instance d'imprimante si le champ réel est Aucun. Si le champ réel n'est pas None, ne faites rien.

main.py


from printer_proxy import PrinterProxy


def main():
    pp = PrinterProxy('Alice')
    print('Le nom est maintenant' + pp.get_printer_name() + 'est.')
    pp.set_printer_name('Bob')
    print('Le nom est maintenant' + pp.get_printer_name() + 'est.')
    pp.my_print('Hello, world.')

if __name__ == '__main__':
    main()

Résultat d'exécution

Le nom est maintenant Alice.
Le nom est maintenant Bob.
Instance d'imprimante(Bob)Est en cours de génération....Terminé.
=== Bob ===
Hello, world.

Résumé

Dans le modèle Proxy, le rôle Proxy agit comme un agent et prend en charge le traitement autant que possible. Dans l'exemple de programme, en utilisant le rôle Proxy, il était possible de retarder le traitement intensif (instanciation) jusqu'au my_print réel.

S'il y a beaucoup de fonctions qui prennent beaucoup de temps à s'initialiser dans la scène d'utilisation réelle, je pense qu'elles ne seront initialisées que lorsqu'il sera temps d'utiliser réellement ces fonctions. Je pense que c'est l'un des modèles de conception les plus couramment utilisés.

référence

Recommended Posts

Modèle de conception #Proxy
Modèle de conception #Adapter
Modèle de conception #Decorator
Modèle de conception #Observer
Modèle de conception #Facade
Modèle de conception #Strategy
Modèle de conception #Singleton
Apprenez le modèle de conception "Proxy" en Python
[Gang of Four] Apprentissage des modèles de conception - Proxy
Design Pattern #Factory, méthode
Design Pattern #Template, méthode
Modèle de proxy en Java
Modèle de conception Oreore: variable glocale
Python Design Pattern - Méthode de modèle
[Gang of Four] Apprentissage des modèles de conception
Résumé du modèle de conception Java GoF
Apprenez le modèle de conception "Prototype" avec Python
[Gang of Four] Apprentissage des modèles de conception --Singleton
[Gang of Four] Apprentissage des modèles de conception - Décorateur
[Gang of Four] Apprentissage des modèles de conception - Visiteur
[Gang of Four] Apprentissage des modèles de conception - Médiateur
Apprenez le modèle de conception "Flyweight" en Python
Apprenez le modèle de conception "Memento" avec Python
Apprenez le modèle de conception "Commande" en Python
[Gang of Four] Apprentissage des modèles de conception - Itérateur
Apprenez le modèle de conception "Visiteur" avec Python
Apprenez le modèle de conception "Mediator" avec Python
Apprenez le modèle de conception "Décorateur" avec Python
Modèle de conception-Itérateur
[Gang of Four] Apprentissage des modèles de conception - Façade
[Gang of Four] Apprentissage des modèles de conception - Composite
[Gang of Four] Apprentissage des modèles de conception - Prototype
Modèle de conception du GoF à partir du problème 1. Génération
Apprenez le modèle de conception "Iterator" avec Python
J'ai étudié les modèles de conception (mémo personnel), partie 8 (modèle proxy, modèle de commande, modèle d'interprétation)
[Gang of Four] Apprentissage des modèles de conception --Mémento
[Gang of Four] Apprentissage des modèles de conception - État
[Gang of Four] Apprentissage des modèles de conception - Interprétation
[Gang of Four] Apprentissage des modèles de conception - Constructeur
Apprenez le modèle de conception «Stratégie» avec Python
[Gang of Four] Apprentissage des modèles de conception - Pont
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
[Gang of Four] Apprentissage des modèles de conception - Stratégie
[Gang of Four] Apprentissage des modèles de conception - Adaptateur
Apprenez le modèle de conception "Façade" avec Python
[Gang of Four] Apprentissage des modèles de conception --Observer
[Gang of Four] Apprentissage des modèles de conception - Commande
Modèle de conception GoF à partir du problème 3. Comportement
[Gang of Four] Apprentissage des modèles de conception - Poids du vol
[Gang of Four] Apprentissage des modèles de conception - Usine abstraite
Apprenez le modèle de conception "Abstract Factory" avec Python
Apprenez le modèle de conception "Méthode de modèle" en Python
[Gang of Four] Apprentissage des modèles de conception - Méthode d'usine
Apprenez le modèle de conception "Méthode d'usine" en Python
[Gang of Four] Apprentissage des modèles de conception - Chaîne de responsabilité
[Gang of Four] Apprentissage des modèles de conception - Méthode du modèle